Les points pour créer une application de minuterie sont publiés dans plusieurs articles. Dans cet article, je vais vous montrer comment créer un écran de réglage qui comprend l'activation / la désactivation du son de l'alarme et l'activation / la désactivation de la barre de progression.
Vous pouvez voir l'exemple de code à partir de l'URL du référentiel Git suivante. https://github.com/msnsk/Qiita_Timer.git
Nous allons créer un écran de réglage. Le PickerView, TimerView et ButtonsView que j'ai créés jusqu'à présent sont tous placés dans MainView et l'application de minuterie n'a pas d'écran autre que MainView.
Cette fois, nous allons créer un écran de réglage séparément de MainView. Les éléments suivants seront affichés sur cet écran de réglage.
À partir du modèle SwiftUI, créez un nouveau fichier nommé SettingView.
Encore une fois, les informations de paramètres seront éventuellement reflétées dans les propriétés de la classe TimeManager, alors ajoutez d'abord le wrapper de propriété @EnvironmentObject pour créer une instance de TimeManager.
SettingView.swift
import SwiftUI
struct SettingView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
Text("Hello, World!")
}
}
Il existe deux principaux types de composants utilisés dans l'affichage de liste dans SwiftUI. L'un est la liste et l'autre la forme.
Form est utilisé pour l'écran de configuration des applications iOS générales, donc cette fois, nous utiliserons Form.
À propos, même si vous divisez certaines sections avec des titres, la liste sera affichée avec toutes les sections, y compris les divisions de section séparées par des bordures, il est donc plus approprié pour organiser des éléments tels que des rappels dans une ligne. ..
En ce qui concerne l'élément de sélection du son d'alarme, nous voulons passer de l'écran de réglage à l'écran de sélection du son, donc placez le composant Form dans le NavigationView. En faisant cela, il est possible de configurer la transition à partir du formulaire vers une autre liste ou formulaire.
SettingView.swift
struct SettingView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
NavigationView {
Form {
}
}
}
}
La configuration de l'écran est supposée comme suit.
Section 1: Alarme liée </ strong>
Section 2: Animation </ strong>
Section 3: Fermez l'écran des paramètres </ strong> --Bouton pour fermer l'écran de réglage
Mettez trois sections dans le formulaire. La première section contient deux Toggle et un NavigationLink. Mettez un Toggle dans la deuxième section. Mettez un bouton dans la troisième section.
Si vous mettez le titre de la section dans Texte dans l'en-tête d'argument de Section, il sera plus facile de comprendre de quelle section il s'agit.
SettingView.swift
struct SettingView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
NavigationView {
Form {
Section(header: Text("Alarm:")) {
Toggle(isOn: ) {
}
Toggle(isOn: ) {
}
NavigationLink(destination: )) {
}
}
Section(header: Text("Animation:")) {
Toggle(isOn: ) {
}
Toggle(isOn: ) {
}
}
Section(header: Text("Save:")) {
Button(action: ) {
}
}
}
}
}
}
Nous avons maintenant besoin d'une propriété pour refléter l'activation / la désactivation du composant Toggle. Cette propriété doit être reflétée dans chaque composant de MainView à partir de l'écran des paramètres. Par exemple, si vous activez une alarme sur l'écran des paramètres, le paramètre sera en fait déclenché dans MainView.
Par conséquent, la propriété qui stocke chaque information de paramètre doit être ajoutée à la classe TimeManager avec le wrapper de propriété @Published.
Ajoutez quatre propriétés à TimeManager pour stocker les informations de configuration du commutateur à bascule. Les quatre éléments suivants seront ajoutés.
TimeManager.swift
class TimeManager: ObservableObject {
//(Autres propriétés omises)
//Stocke le nom du son correspondant à la valeur de la propriété soundID
@Published var soundName: String = "Beat"
//Son d'alarme activé/Réglage Off
@Published var isAlarmOn: Bool = true
//Vibration sur/Réglage Off
@Published var isVibrationOn: Bool = true
//Affichage de la barre de progression sur/Réglage Off
@Published var isProgressBarOn: Bool = true
//Affichage de l'animation d'effet sur/Réglage Off
@Published var isEffectAnimationOn: Bool = true
//La méthode de publication de la classe Timer qui est activée toutes les secondes
var timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
//(Méthode omise)
}
Dans l'argument de méthode Toggle isOn, spécifiez la propriété du TimeManager pour laquelle vous souhaitez stocker les paramètres. À ce stade, vous devez le préfixer avec le symbole $. En outre, dans la fermeture, entrez le nom que vous souhaitez afficher comme élément de réglage dans le formulaire avec texte.
Toggle(isOn: $timeManager.isAlarmOn) {
Text("Alarm Sound")
}
De cette façon, nous décrirons tous les arguments et fermetures Toggle pour le moment.
En ce qui concerne l'élément de sélection du son d'alarme, il n'y a pas encore d'écran de sélection, alors commentez-le une fois.
L'étiquette du dernier bouton d'enregistrement est fournie avec du texte et une icône de coche. Puisque nous voulons le placer au centre dans le sens horizontal, nous l'amènerons au centre en l'entourant de HStack et en plaçant Spacer de gauche à droite. L'action lorsque vous appuyez sur le bouton est toujours vide.
SettingView.swift
struct SettingView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
NavigationView {
Form {
Section(header: Text("Alarm:")) {
Toggle(isOn: $timeManager.isAlarmOn) {
Text("Alarm Sound")
}
Toggle(isOn: $timeManager.isVibrationOn) {
Text("Vibration")
}
// NavigationLink(destination: ) {
//
// }
}
Section(header: Text("Animation:")) {
Toggle(isOn: $timeManager.isProgressBarOn) {
Text("Progress Bar")
}
Toggle(isOn: $timeManager.isEffectAnimationOn) {
Text("Effect Animation")
}
}
Section(header: Text("Save:")) {
Button(action: ) {
HStack {
Spacer()
Text("Done")
Image(systemName: "checkmark.circle")
Spacer()
}
}
}
}
}
}
}
Vérifiez l'affichage de SettingView sur le canevas. Voici le code de l'aperçu.
struct SettingView_Previews: PreviewProvider {
static var previews: some View {
SettingView().environmentObject(TimeManager())
}
}
Cela devrait ressembler à l'image ci-dessous.
Affichez le SettingView de manière modale. Modal est un nom abrégé pour une fenêtre modale, ce qui revient à être inopérant lorsque la fenêtre est ouverte.
Préparez une variable avec un wrapper de propriété appelé @Environment (\ .presentationMode) dans SettingView.
Ensuite, écrivez le code pour fermer le modal dans la fermeture de l'argument d'action du bouton Enregistrer qui est tapé lors de la fermeture de l'écran de réglage.
self.presentationMode.wrappedValue.dismiss()
SettingView.swift
struct SettingView: View {
//Propriétés d'utilisation des feuilles modales
@Environment(\.presentationMode) var presentationMode
@EnvironmentObject var timeManager: TimeManager
var body: some View {
NavigationView {
Form {
//(Autres sections omises)
Section(header: Text("Save:")) {
Button(action: {
//Appuyez pour fermer le modal
self.presentationMode.wrappedValue.dismiss()
}) {
HStack {
Spacer()
Text("Done")
Image(systemName: "checkmark.circle")
Spacer()
}
}
}
}
}
}
}
Cette fois, au contraire, nous allons préparer un bouton dans MainView pour ouvrir l'écran de réglage. Avec un seul bouton, créez une vue facile à comprendre. Créons maintenant un nouveau fichier SwiftUI nommé SettingButton.
SettingButtonView.swift
import SwiftUI
struct SettingButtonView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
}
}
L'icône du bouton utilise "ellipsis.circle.fill" de SF Symbols.
SettingButtonView.swift
import SwiftUI
struct SettingButtonView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
Image(systemName: "ellipsis.circle.fill")
}
}
La taille du bouton de réglage est légèrement plus petite que celle du bouton de démarrage / pause et du bouton de réinitialisation, utilisez donc le modificateur de cadre pour définir les tailles verticale et horizontale.
SettingButtonView.swift
import SwiftUI
struct SettingButtonView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
Image(systemName: "ellipsis.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
}
}
Maintenant, créez une propriété de type Bool dans la classe TimeManager qui affiche / masque le modal. Nommez-le
TimeManager.swift
class TimeManager: ObservableObject {
//(Autres propriétés omises)
//Affichage de l'écran de réglage/Cacher
@Published var isSetting: Bool = false
//(Méthode omise)
}
Et enfin, revenez à SettingButtonView et ajoutez .onTapGesture pour que la propriété isSetting de TimeManager soit vraie à l'intérieur de la fermeture {}.
SettingButtonView.swift
import SwiftUI
struct SettingButtonView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
Image(systemName: "ellipsis.circle.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 40, height: 40)
.onTapGesture {
self.timeManager.isSetting = true
}
}
Vérifions l'écran avec Canvas. Voici le code de l'aperçu.
struct SettingButton_Previews: PreviewProvider {
static var previews: some View {
SettingButtonView()
.environmentObject(TimeManager())
.previewLayout(.sizeThatFits)
}
}
Cela devrait ressembler à l'image ci-dessous.
Ajoutons maintenant SettingButtonView à ManiView.
L'endroit à ajouter est le même en bas de l'écran que les boutons de démarrage / pause et de réinitialisation sous PickerView et TimerView. Par conséquent, dans ZStack {}, ButtonsView et SettingButtonView sont superposés. Peu importe quel est l'avant ou l'arrière.
SettingBottonView ajoute un modificateur de remplissage (.bottom) ainsi que ButtonsView, car il est préférable que tous les boutons soient alignés dans le sens vertical.
Ajoutez ensuite un modificateur .sheet () pour afficher la fenêtre modale. L'argument isPresented spécifie une propriété de type Bool dont le modal est affiché lorsqu'il est vrai. En d'autres termes, il s'agit de la propriété isSetting de la classe TimeManager préparée précédemment.
Dans la fermeture {}, décrivez la vue que vous souhaitez afficher de manière modale. Ici, c'est SettingView (). À ce stade, assurez-vous de décrire également la propriété .environmentObject (self.timeManager).
MainView.swift
struct MainView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
ZStack {
if timeManager.timerStatus == .stopped {
PickerView()
} else {
TimerView()
}
VStack {
Spacer()
//Boutons de superpositionView et SettingButtonView en couches
ZStack {
ButtonsView()
.padding(.bottom)
//Bouton de réglage ajouté
SettingButtonView()
.padding(.bottom)
//Afficher SettingView de manière modale lorsque la propriété isSetting est true
.sheet(isPresented: $timeManager.isSetting) {
SettingView()
.environmentObject(self.timeManager)
}
}
}
}
//(.partie modificateur osReceive omise)
}
}
Puisque nous avons ajouté des éléments de réglage du son d'alarme et des vibrations, nous émettrons une alarme lorsque la minuterie au plus près du modificateur onReceive de MainView atteint 0, et décrivons la description pour activer la vibration si le paramètre est activé. Il s'agit simplement d'un branchement conditionnel dans l'instruction if en fonction des valeurs des propriétés isAlarmOn et isVibrationOn de la classe TimeManager.
MainView.swift
struct MainView: View {
@EnvironmentObject var timeManager: TimeManager
var body: some View {
ZStack {
//(Voir la description omise)
}
//Exécute le code dans la fermeture déclenchée par une minuterie qui s'active à chaque heure spécifiée (1 seconde)
.onReceive(timeManager.timer) { _ in
//L'état de la minuterie est.Ne rien faire sauf courir
guard self.timeManager.timerStatus == .running else { return }
//Si le temps restant est supérieur à 0
if self.timeManager.duration > 0 {
//Du temps restant-0.05
self.timeManager.duration -= 0.05
//Lorsque le temps restant est égal ou inférieur à 0
} else {
//État de la minuterie.Changer pour arrêté
self.timeManager.timerStatus = .stopped
//Sonner une alarme
if timeManager.isAlarmOn {
AudioServicesPlayAlertSoundWithCompletion(self.timeManager.soundID, nil)
}
//Activer la vibration
if timeManager.isVibrationOn {
AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) {}
}
}
}
}
}
Vérifions MainView avec Canvas. Voici le code de l'aperçu.
struct MainView_Previews: PreviewProvider {
static var previews: some View {
Group {
MainView().environmentObject(TimeManager())
}
}
}
Cela devrait ressembler à l'image ci-dessous. Le bouton de réglage est placé entre le bouton de démarrage et le bouton de réinitialisation avec la même hauteur.
Maintenant, lorsque vous appuyez sur le bouton de réglage, l'écran de réglage s'affiche de manière modale. Veuillez le vérifier avec Canvas.
Cette fois, j'ai créé une vue avec uniquement des boutons de réglage en tant que SettingButtonView, mais je pense que c'est correct de la mettre ensemble dans la ButtonsView créée précédemment.
Recommended Posts