Les points pour créer une application de minuterie sont publiés dans plusieurs articles. Dans cet article, je vais fournir les étapes pour implémenter les fonctions de démarrage, de pause et de réinitialisation qui sont les principales opérations du compte à rebours.
Vous pouvez voir l'exemple de code à partir de l'URL du référentiel Git suivante. https://github.com/msnsk/Qiita_Timer.git
Créez une propriété dans la classe TimeManager qui représente l'état du minuteur. Le statut est le suivant.
--running: Le compte à rebours est en cours --pause: le minuteur est mis en pause et peut être repris --stop: l'état où le minuteur a terminé le compte à rebours
En guise de préparation, créez une nouvelle énumération dans le fichier Data.swift qui représente l'état du minuteur.
Data.swift
//(Autre énumération omise)
enum TimerStatus {
case running
case pause
case stopped
}
Créez une propriété dans la classe TimeManager avec l'énumération créée comme type de données. La valeur par défaut de cette propriété doit être .stopped, car le minuteur doit être inactif jusqu'à ce que l'utilisateur appuie sur le bouton de démarrage.
TimeManager.swift
class TimeManager: ObservableObject {
//(Autres propriétés omises)
//État de la minuterie
@Published var timerStatus: TimerStatus = .stopped
//(Méthode omise)
Nous n'avons pas encore créé de boutons, mais nous allons créer des méthodes pour démarrer, mettre en pause et terminer complètement le minuteur la première fois que vous appuyez sur chaque bouton. En d'autres termes, ces méthodes modifient la valeur de la propriété d'état du minuteur créée précédemment à chaque fois.
TimeManager.swift
class TimeManager: ObservableObject {
//(Propriété omise)
//(Autres méthodes omises)
//Méthode activée lorsque vous appuyez sur le bouton de démarrage
func start() {
//État de la minuterie.prêt à courir
timerStatus = .running
}
//Méthode activée lorsque vous appuyez sur le bouton de pause
func pause() {
//État de la minuterie.pause
timerStatus = .pause
}
//Méthode qui est activée lorsque le bouton de réinitialisation est appuyé
func reset() {
//État de la minuterie.Arrêtez
timerStatus = .stopped
//Défini de force sur 0 même si le temps restant n'est pas encore 0
duration = 0
}
}
Créez un nouveau fichier nommé ButtonsView.swift. Une structure portant le même nom est générée.
Puisqu'il est nécessaire de lier l'opération de bouton à la propriété timerStatus de la classe TimeManager créée à l'étape 1, créez également une instance de la classe TimeManager dans cette vue. Comme d'habitude, j'ajouterai également un wrapper de propriété pour @EnvironmentObject.
ButtonsView.swift
import SwiftUI
@EnvironmentObject var timeManager: TimeManager
struct ButtonsView: View {
var body: some View {
}
}
Le bouton de démarrage et le bouton d'arrêt seront affichés au même endroit sur l'écran. Selon l'état de la minuterie, le bouton affiché à l'écran est conditionnel.
--Afficher le bouton de pause lors de l'exécution --Afficher le bouton de démarrage lorsque .pause ou .stopped
Les deux icônes de bouton suivantes provenant des symboles Apple SF authentiques sont utilisées (couramment utilisées pour la lecture et la mise en pause du son).
--play.circle.fill: bouton Démarrer --pause.circle.fill: bouton Pause
Lorsque l'affichage du temps restant est 0, cela signifie que vous ne pouvez pas démarrer ou mettre en pause, alors créez une branche conditionnelle avec le modificateur de transparence .opacity.
Spécifiez la méthode setTimer de sorte que lorsque le bouton est touché, le PickerView s'affiche (et l'heure est définie), la minuterie est définie lorsque le bouton Démarrer est appuyé. Lorsque le PickerView est affiché, l'état du minuteur est .stopped, donc écrivez-le dans le modificateur onTapGesture avec une instruction if.
Lorsque cette méthode setTimer est exécutée en appuyant sur le bouton, le temps défini dans la propriété duration du temps restant et la propriété maxValue du temps maximum sont affectés. Écrivez une instruction if dans le modificateur onTapGesture afin que la méthode de démarrage soit également exécutée lorsque cette durée est différente de zéro et que l'état du minuteur n'est pas en cours d'exécution.
Comme autre condition, l'instruction if précédente est suivie de l'instruction if else afin qu'elle ne puisse être suspendue que lorsque l'état du minuteur est.
ButtonsView.swift
struct ButtonsView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
//running:Bouton Pause/pause or stopped:Bouton Start
Image(systemName: self.timeManager.timerStatus == .running ? "pause.circle.fill" : "play.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 75, height: 75)
//Espace sur le côté droit du bouton et sur le bord de l'écran
.padding(.trailing)
//Si les heures, les minutes et les secondes du sélecteur sont toutes à 0, la transparence du bouton est définie sur 0..À 1 sinon à 1 (opaque)
.opacity(self.timeManager.hourSelection == 0 && self.timeManager.minSelection == 0 && self.timeManager.secSelection == 0 ? 0.1 : 1)
//Action en appuyant sur un bouton
.onTapGesture {
if timeManager.timerStatus == .stopped {
self.timeManager.setTimer()
}
//Le temps restant est différent de zéro et l'état de la minuterie est.Autre que courir
if timeManager.duration != 0 && timeManager.timerStatus != .running {
self.timeManager.start()
//L'état de la minuterie est.Pour courrir
} else if timeManager.timerStatus == .running {
self.timeManager.pause()
}
}
}
}
Créez plus de boutons de réinitialisation dans ButtonsView.
Appuyez sur ce bouton pour activer la méthode de réinitialisation de la classe TimeManager créée à l'étape 2.
Pour l'icône du bouton, nous avons adopté "stop.circle.fill" de SF Symbols.
Écrivez une instruction if dans le modificateur onTapGesture afin que la méthode de réinitialisation soit déclenchée si l'état du minuteur est différent de .stopped.
En ce qui concerne la disposition des boutons, je veux placer le bouton de réinitialisation sur le côté gauche de l'écran et le bouton de démarrage / pause créé plus tôt sur le côté droit de l'écran, alors placez les deux boutons à l'intérieur du HStack.
Si la valeur par défaut est laissée, les deux boutons seront centrés sur l'écran, insérez donc un espaceur entre les boutons afin que les boutons soient des deux côtés de l'écran.
Si vous déplacez le bouton trop près du bord de l'écran, il aura l'air mauvais, alors je l'ai ajusté avec un remplissage.
ButtonsView.swift
struct ButtonsView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
//Bouton de réinitialisation à gauche de l'écran dans HStack, démarrer à droite/Bouton Pause
HStack {
//Bouton de réinitialisation
Image(systemName: "stop.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 75, height: 75)
//Laisser de l'espace sur le côté gauche du bouton et sur le bord de l'écran
.padding(.leading)
//Transparence 0 lorsque l'état de la minuterie se termine.À 1, sinon opaque
.opacity(self.timeManager.timerStatus == .stopped ? 0.1 : 1)
//Action en appuyant sur un bouton
.onTapGesture {
//L'état de la minuterie est.Autre que arrêté
if timeManager.timerStatus != .stopped {
self.timeManager.reset()
}
//Espacement entre les boutons
Spacer()
//running:Bouton Pause/pause or stopped:Bouton Start
Image(systemName: self.timeManager.timerStatus == .running ? "pause.circle.fill" : "play.circle.fill")
//(Modificateur omis)
}
}
}
Voyons à quoi ressemble le ButtonsView sur Canvas. Vous trouverez ci-dessous le code de l'aperçu.
struct ButtonsView_Previews: PreviewProvider {
static var previews: some View {
ButtonsView()
.environmentObject(TimeManager())
.previewLayout(.sizeThatFits)
}
}
Cela ressemble à l'image ci-dessous. Étant donné que la valeur initiale de l'état de la minuterie est .stopped, le bouton est grisé et affiché comme ne répondant pas lorsqu'il est touché.
PickerView et TimerView ont déjà été ajoutés à MainView.
Écrivez une instruction if-else pour que la vue affichée dépende de l'état de la minuterie.
PickerView et TimerView sont les deux composants les plus importants de cette application de minuterie, ils doivent donc être centrés sur l'écran (sauf si vous spécifiez un emplacement, ils seront centrés horizontalement et verticalement par défaut).
Compte tenu de l'opération avec le doigt d'un appareil iOS tel que l'iPhone, je veux placer le ButtonsView que je veux ajouter cette fois sous PickerView / TimerView et également près du bas de l'écran, j'ai donc fait de ZStack une couche distincte de PickerView / TimerView et VStack Déplacez ButtonsView vers le bas en plaçant une entretoise au-dessus de ButtonsView. Cependant, cela n'a pas l'air bien au bord de l'écran, alors faites des ajustements fins avec le modificateur padding (.bottom).
MainView.swift
struct MainView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
ZStack {
if timeManager.timerStatus == .stopped {
PickerView()
} else {
TimerView()
}
VStack {
Spacer()
ButtonsView()
.padding(.bottom)
}
}
}
}
Vérifiez l'affichage de MainView sur Canvas. Code pour l'aperçu.
struct MainView_Previews: PreviewProvider {
static var previews: some View {
Group {
MainView().environmentObject(TimeManager())
}
}
}
Puisque la valeur initiale de l'état du minuteur est .stopped, la branche conditionnelle de l'instruction if affiche uniquement PickerView et masque le TimerView qui se chevauche dans ZStack. ButtonsView est poussé par Spacer dans VStack et est situé en bas de l'écran.
La prochaine fois, nous mettrons en œuvre un affichage du compte à rebours du temps restant.
Recommended Posts