[SWIFT] Développement d'applications iOS: application Timer (3. bouton Démarrer / Arrêter, bouton Réinitialiser)

スクリーンショット 2020-10-28 10.31.52.png

Contenu

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.

environnement

Dépôt Git

Vous pouvez voir l'exemple de code à partir de l'URL du référentiel Git suivante. https://github.com/msnsk/Qiita_Timer.git

procédure

  1. Créez une propriété dans TimeManager qui indique l'état du minuteur
  2. Créez une méthode dans TimeManager pour changer l'état du minuteur
  3. Créer ButtonsView
  4. Créez un bouton de démarrage / arrêt dans ButtonsView
  5. Créez un bouton de réinitialisation dans ButtonsView
  6. Placez ButtonsView sur MainView

1. Créez une propriété dans TimeManager qui indique l'état du minuteur

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)

2. Créez une méthode dans TimeManager pour changer l'état du minuteur

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
    }
}

3. Créer ButtonsView

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 {

    }
}

4. Créez un bouton de démarrage / arrêt dans ButtonsView

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()
                }
            }
    }
}

5. Créez un bouton de réinitialisation dans ButtonsView

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é. スクリーンショット 2020-10-28 10.32.02.png

6. Placez ButtonsView sur MainView

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. スクリーンショット 2020-10-28 10.32.20.png

La prochaine fois, nous mettrons en œuvre un affichage du compte à rebours du temps restant.

Recommended Posts

Développement d'applications iOS: application Timer (3. bouton Démarrer / Arrêter, bouton Réinitialiser)
Développement d'applications iOS: application Timer (résumé)
Développement d'applications iOS: application Timer (4. Implémentation du compte à rebours)
Développement d'applications iOS: application Timer (1. réglage de l'heure de la minuterie)
Développement d'applications iOS: application Timer (10. Créer une animation)
Développement d'applications iOS: application Timer (6. Création de l'écran de réglage)
Développement d'applications iOS: application Timer (8. Implémentation de la barre de progression)
Développement d'applications iOS: application Timer (7. Mise en œuvre de la sélection du son d'alarme)
Développement d'applications iOS: application Timer (5. Implémentation d'alarme et de vibration)
Journal complet de développement d'applications IOS pour l'auto-apprentissage
Feuille de route des compétences de développement d'applications iOS (introduction)