[SWIFT] Développement d'applications iOS: application Timer (1. réglage de l'heure de la minuterie)

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

Contenu

Les points pour créer une application de minuterie sont publiés dans plusieurs articles. Dans cet article, j'écrirai sur la création d'une vue qui définit la durée maximale du compte à rebours jusqu'au minuteur.

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 classe TimeManager
  2. Créez une propriété pour stocker le temps du compte à rebours dans TimeManager
  3. Créez PickerView
  4. Placez le sélecteur dans PickerView
  5. Créez une méthode pour refléter l'heure définie dans TimeManager
  6. Créez une méthode pour afficher le temps restant pendant le compte à rebours dans TimeManager

1. Créez une classe TimeManager

Créez un fichier appelé TimeManager.swift et créez une classe avec le même nom. En supposant plus tard, nous appliquerons un protocole appelé ObservableObject. ObservableObject En termes simples, le protocole est-il nécessaire pour garder un œil sur les propriétés des variables dont les valeurs changent. Si vous préparez une propriété (var) avec le préfixe du mot-clé @Published (Property Wrapper) dans une classe à laquelle ce protocole est appliqué, sa valeur peut toujours être référencée à partir d'autres vues.

TimeManager.swift


import SwiftUI

class TimeManager: ObservableObject {

}

2. Créez une propriété pour stocker le temps du compte à rebours dans TimeManager

Préparez les cinq propriétés suivantes pour définir la durée du compte à rebours.

Je veux que la valeur de chaque propriété soit toujours visible par les autres vues, je place donc le wrapper de propriété @Published devant var.

Étant donné que les heures, les minutes et les secondes sont obtenues à partir de Picker en tant que type Int, spécifiez Int comme type de données. D'autre part, spécifiez Double pour le temps restant et le temps maximum. Il s'agit de rendre les valeurs de ces propriétés plus accessibles ultérieurement. Lors de la programmation à l'aide d'une variable, une erreur se produira à moins que les types de données de la variable ne soient unifiés.

Chaque propriété doit contenir une valeur par défaut, laissez-la donc à 0.

TimeManager.swift


class TimeManager: ObservableObject {
    //Set avec Picker"temps"Variable à stocker
    @Published var hourSelection: Int = 0
    //Set avec Picker"Minutes"Variable à stocker
    @Published var minSelection: Int = 0
    //Set avec Picker"Secondes"Variable à stocker
    @Published var secSelection: Int = 0
    //Compte à rebours restant
    @Published var duration: Double = 0
    //Temps maximum avant le début du compte à rebours
    @Published var maxValue: Double = 0
}

De plus, je souhaite modifier le format de l'affichage de l'heure en fonction de la durée du compte à rebours défini (par exemple, "02:30:00" si réglé sur 2 heures 30 minutes, "05:00" s'il est réglé sur 5 minutes, s'il est réglé sur 30 secondes Je veux afficher "30"), alors créez une énumération.

Créez un nouveau fichier appelé Data.swift et créez une énumération appelée TimeFormat.

Data.swift



import SwiftUI

enum TimeFormat {
    case hr
    case min
    case sec
}

Ensuite, préparez une propriété qui spécifie l'énumération de TimeFormat créée dans la classe TimeManager comme type afin que le format d'affichage puisse être spécifié. La valeur par défaut doit être min pour l'instant.

TimeManager.swift


class TimeManager: ObservableObject {
    //(Omettre la propriété créée précédemment)
    //Format d'affichage de l'heure qui change en fonction de l'heure réglée de 1 heure ou plus, moins de 1 heure, 1 minute ou plus, moins de 1 minute, 1 seconde ou plus
    @Published var displayedTimeFormat: TimeFormat = .min
}

3. Créez PickerView

Créez un nouveau fichier appelé PickerView.swift et créez un type de vue Struct (structure) avec le même nom.

PickerView.swift


import SwiftUI

struct PickerView: View {
    var body: some View {
    }
}

Commencez par créer les propriétés requises. Maintenant, créez une instance de la classe TimeManager que vous avez créée précédemment. En préfixant le mot clé @EnvironmentObject (Property Wrapper), vous pouvez toujours faire référence à la valeur de la variable changeante de TimeManager. Autrement dit, la propriété @Published dans la classe appliquée au protocole ObservableObject et la propriété @EnvironmentObject dans la structure appliquée au protocole View sont associées et toujours synchronisées.

PickerView.swift


struct PickerView: View {
    //Créer une instance de TimeManager
    @EnvironmentObject var timeManager: TimeManager
    //Largeur de l'écran de l'appareil
    let screenWidth = UIScreen.main.bounds.width
    //Hauteur de l'écran de l'appareil
    let screenHeight = UIScreen.main.bounds.height
    //Numéro d'unité de temps configurable: tableau d'entiers de 0 à 23
    var hours = [Int](0..<24)
    //Nombre de minutes configurable: tableau d'entiers de 0 à 59
    var minutes = [Int](0..<60)
    //Nombre configurable en secondes: tableau d'entiers de 0 à 59
    var seconds = [Int](0..<60)

struct PickerView: View {
    var body: some View {
    }
}

4. Placez le sélecteur dans le PickerView

À l'intérieur du PickerView, utilisez HStack pour organiser les composants suivants horizontalement dans l'ordre à partir de la gauche.

Pour la sélection de l'argument Time Picker, spécifiez la propriété hourSelection de l'instance timeManager créée précédemment. Cela entraînera l'affectation de la valeur sélectionnée par Picker à la propriété du même nom dans la classe TimeManager.

Dans le {} du sélecteur, forceEach à afficher un nombre dans le sélecteur pour chacun des 0 à 23 et spécifiez la valeur (y compris le type de données) à acquérir lorsque l'heure est effectivement sélectionnée dans le sélecteur par le modificateur de balise. .. La valeur à acquérir est de type Int et la propriété hourSelection de la destination de réflexion TimeManager est également mise en correspondance avec le type Int.

Une fois que vous avez un sélecteur d'heure, spécifiez que le composant Texte doit afficher l'unité "heure".

De la même manière, créez un sélecteur et un texte pendant des minutes et des secondes.

PickerView.swift


struct PickerView: View {
    //(Description de la partie de propriété omise)
    
    var body: some View {
            //Sélecteur d'heures, de minutes, de secondes et de texte montrant chaque unité côte à côte dans HStack
            HStack {
                //Sélecteur horaire
                Picker(selection: self.$timeManager.hourSelection, label: Text("hour")) {
                    ForEach(0 ..< self.hours.count) { index in
                        Text("\(self.hours[index])")
                            .tag(index)
                    }
                }
                //Spécifiez un style de roue qui pivote de haut en bas
                .pickerStyle(WheelPickerStyle())
                //Taille de l'écran de largeur du sélecteur x 0.1, taille de l'écran de hauteur x 0.Spécifié par 4
                .frame(width: self.screenWidth * 0.1, height: self.screenWidth * 0.4)
                //Clip avec le cadre supérieur et masquer la partie qui dépasse le cadre
                .clipped()
                //Texte représentant l'unité de temps
                Text("hour")
                    .font(.headline)
                
                //Sélecteur de minutes
                Picker(selection: self.$timeManager.minSelection, label: Text("minute")) {
                    ForEach(0 ..< self.minutes.count) { index in
                        Text("\(self.minutes[index])")
                            .tag(index)
                    }
                }
                .pickerStyle(WheelPickerStyle())
                .frame(width: self.screenWidth * 0.1, height: self.screenWidth * 0.4)
                .clipped()
                //Texte représentant les minutes
                Text("min")
                    .font(.headline)
                
                //Picker en quelques secondes
                Picker(selection: self.$timeManager.secSelection, label: Text("second")) {
                    ForEach(0 ..< self.seconds.count) { index in
                        Text("\(self.seconds[index])")
                            .tag(index)
                    }
                }
                .pickerStyle(WheelPickerStyle())
                .frame(width:self.screenWidth * 0.1, height: self.screenWidth * 0.4)
                .clipped()
                //Texte représentant les secondes
                Text("sec")
                    .font(.headline)
            }
    }
}

5. Créez une méthode pour refléter l'heure définie dans TimeManager

Créez une méthode appelée setTimer dans la classe TimeManager. Étant donné que les valeurs des propriétés time, minute et second de TimeManager peuvent être obtenues à partir de PickerView, ces valeurs sont converties en secondes et totalisées, et reflétées dans les propriétés de temps restant et de temps maximum. Dans le même temps, le format d'affichage de l'heure doit être un branchement conditionnel en fonction du temps total.

TimeManager.swift


class TimeManager: ObservableObject {
    //Set avec Picker"temps"Variable à stocker
    @Published var hourSelection: Int = 0
    //Set avec Picker"Minutes"Variable à stocker
    @Published var minSelection: Int = 0
    //Set avec Picker"Secondes"Variable à stocker
    @Published var secSelection: Int = 0
    //Compte à rebours restant
    @Published var duration: Double = 0
    //Temps maximum avant le début du compte à rebours
    @Published var maxValue: Double = 0
    //Format d'affichage de l'heure qui change en fonction de l'heure réglée de 1 heure ou plus, moins de 1 heure, 1 minute ou plus, moins de 1 minute, 1 seconde ou plus
    @Published var displayedTimeFormat: TimeFormat = .min
    
    //Calculez le temps restant du compte à rebours et le temps maximum avant le début du compte à rebours à partir de la valeur obtenue par Picker,
    //Le format d'affichage de l'heure est également spécifié par la valeur
    func setTimer() {
        //Calculez le temps restant en convertissant toutes les valeurs d'heures, de minutes et de secondes obtenues à partir de Picker en secondes et en les totalisant.
        duration = Double(hourSelection * 3600 + minSelection * 60 + secSelection)
        //Lorsque l'heure est réglée avec Picker=Temps restant car c'est avant le début du compte à rebours=Temps maximum
        maxValue = duration
        
        //Spécifiez le format d'affichage de l'heure à partir du temps restant (temps maximum)
        //Format 00 pendant moins de 60 secondes, 00 pendant 60 secondes ou plus et moins de 3600 secondes:Format 00, 00 pendant 3600 secondes ou plus:00:Format 00
        if duration < 60 {
            displayedTimeFormat = .sec
        } else if duration < 3600 {
            displayedTimeFormat = .min
        } else {
            displayedTimeFormat = .hr
        }
    }
}

En outre, ajoutez un bouton à PickerView afin que la méthode setTimer ci-dessus puisse être activée au moment où l'heure est définie dans PickerView. Cela est dû au fait que la formule "temps maximum = temps restant" est incluse, elle est donc idéale avant le compte à rebours, c'est-à-dire immédiatement après l'opération de réglage de l'heure.

Pour l'icône du bouton, utilisez "checkmark.circle.fill" des véritables symboles SF d'Apple.

Le modificateur .offset est placé légèrement vers le bas à partir de l'emplacement central par défaut et ajusté de manière à ne pas chevaucher PickerView.

Avec le modificateur .opacity, si les heures, les minutes et les secondes sont toutes définies sur 0, la transparence est définie sur 10% (x 0,1) et il est visuellement exprimé que vous ne pouvez pas appuyer maintenant.

Lors de la saisie de l'argument du modificateur, au lieu d'utiliser if et else, écrivez "△△? □□: ○○" pour compléter le sens de "Si △△, alors □□, sinon ○○". Il est pratique de se voir attribuer un argument vers lequel effectuer un branchement conditionnel. De plus, "&&" signifie "katsu" et est utilisé pour exprimer des cas où plusieurs conditions sont remplies.

.modificateur onTapGesture{}Si la valeur de la propriété heure, minute ou seconde n'est pas égale à 0, la méthode setTimer sera déclenchée lorsqu'elle sera appuyée. "" Dans l'instruction if||"" Signifie "ou".

PickerView.swift


struct PickerView: View {
    //Créer une instance de TimeManager
    @EnvironmentObject var timeManager: TimeManager
    //Largeur de l'écran de l'appareil
    let screenWidth = UIScreen.main.bounds.width
    //Hauteur de l'écran de l'appareil
    let screenHeight = UIScreen.main.bounds.height
    //Numéro d'unité de temps réglable
    var hours = [Int](0..<24)
    //Numéro de minute réglable
    var minutes = [Int](0..<60)
    //Nombre configurable en secondes
    var seconds = [Int](0..<60)
    
    var body: some View {
        //Organisez les boutons de manière à ce qu'ils se chevauchent avec Picker dans ZStack
        ZStack{
            //Sélecteur d'heures, de minutes, de secondes et de texte montrant chaque unité côte à côte dans HStack
            HStack {
                //(Pièce de sélecteur omise)
            }
            
            //Icône de coche pour confirmer le paramètre en appuyant sur
            Image(systemName: "checkmark.circle.fill")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 35, height: 35)
                .offset(y: self.screenWidth * 0.32)
                .opacity(self.timeManager.hourSelection == 0 && self.timeManager.minSelection == 0 && self.timeManager.secSelection == 0 ? 0.1 : 1)
                .onTapGesture {
                    if self.timeManager.hourSelection != 0 || self.timeManager.minSelection != 0 || self.timeManager.secSelection != 0 {
                        self.timeManager.setTimer()
                    }
            }
        }
    }
}

6. Créez une méthode pour afficher le temps restant pendant le compte à rebours dans TimeManager

Faites-en une méthode nommée displayTimer. Renvoie une valeur de retour de type String.

Le calcul du temps restant est arithmétique, mais il est le suivant. Soit dit en passant,% est un opérateur qui peut calculer le reste de la division.

--Temps restant total (secondes) / 3600 (secondes) = temps restant (heures) --Temps restant total (secondes)% 3600 (secondes) / 60 (secondes) = temps restant (minutes) --Temps restant total (secondes) / 3600 (secondes)% 60 (secondes) = temps restant (secondes)

Les trois valeurs numériques obtenues par le calcul ci-dessus sont affichées côte à côte à l'écran sous forme de données de type chaîne de caractères.

String(format: "%02d:%02d:%02d", hr, min, sec)

Ce code est écrit sous forme de chaîne (format: «spécifier le nombre de chiffres», valeur). En particulier,% 02d dans "" signifie que le nombre total de chiffres est de 2 et s'il est inférieur à 2 chiffres, il est rempli avec 0 à partir du plus grand chiffre. Ensuite, les valeurs répertoriées après% 02d sont séparées par des virgules et sont entrées dans l'ordre à partir de la gauche.

Par exemple, ce qui suit s'affiche à l'écran.

--Si le temps restant est de 4000 secondes 01:06:40 --Si le temps restant est de 350 secondes, 05:50 ――Si le temps restant est de 7 secondes, 07

TimeManager.swift


class TimeManager: ObservableObject {
    //(réduction)
    
    //Méthode d'affichage du temps restant pendant le compte à rebours
    func displayTimer() -> String {
        //Temps restant (unité d'heure)=Temps total restant (secondes)/3600 secondes
        let hr = Int(duration) / 3600
        //Temps restant (en minutes)=Temps total restant (secondes)/Résiduel divisé par 3600 secondes/60 secondes
        let min = Int(duration) % 3600 / 60
        //Temps restant (en secondes)=Temps total restant (secondes)/Résiduel divisé par 3600 secondes/Résiduel divisé par 60 secondes
        let sec = Int(duration) % 3600 % 60
        
        //Branchez conditionnellement le format d'affichage de l'heure en fonction du résultat de la méthode setTimer et reflétez les trois constantes ci-dessus en combinaison.
        switch displayedTimeFormat {
        case .hr:
            return String(format: "%02d:%02d:%02d", hr, min, sec)
        case .min:
            return String(format: "%02d:%02d", min, sec)
        case .sec:
            return String(format: "%02d", sec)
        }
    }
}

Le PickerView créé jusqu'à présent devrait ressembler à l'image ci-dessous. スクリーンショット 2020-10-28 1.38.43.png

La prochaine fois, nous recalculerons le temps restant à partir de l'heure définie dans Picker et afficherons la minuterie à l'écran.

Recommended Posts

Développement d'applications iOS: application Timer (1. réglage de l'heure de la minuterie)
Développement d'applications iOS: application Timer (2. affichage de la minuterie)
Développement d'applications iOS: application Timer (résumé)
Développement d'applications iOS: application Timer (6. Création de l'écran de réglage)
Développement d'applications iOS: application Timer (4. Implémentation du compte à rebours)
Développement d'applications iOS: application Timer (10. Créer une animation)
Développement d'applications iOS: application Timer (8. Implémentation de la barre de progression)
Développement d'applications iOS: application Timer (3. bouton Démarrer / Arrêter, bouton Réinitialiser)
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)
Développement d'applications iOS: application Timer (9. Personnalisez la couleur de la barre de progression)
Journal complet de développement d'applications IOS pour l'auto-apprentissage
L'ingénieur iOS démarre le développement Android
Lancement du développement personnel de l'application Android
Développement d'applications ROS sur Android
Développement ATDD sur iOS (édition de base)