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.
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 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 {
}
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
}
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 {
}
}
À 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)
}
}
}
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()
}
}
}
}
}
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.
La prochaine fois, nous recalculerons le temps restant à partir de l'heure définie dans Picker et afficherons la minuterie à l'écran.
Recommended Posts