[SWIFT] Développement d'applications iOS: application Timer (7. Mise en œuvre de la sélection du son d'alarme)

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

Contenu

Les points pour créer une application de minuterie sont publiés dans plusieurs articles. Dans cet article, je publierai sur la mise en œuvre de l'écran de sélection du son d'alarme.

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. Examiner les éléments (propriété) requis pour la structure sonore de l'alarme
  2. Créez une structure sonore d'alarme dans les données 3.Faites une liste des sons d'alarme
  3. Autoriser le son de l'alarme à être auditionné
  4. Refléter le son d'alarme sélectionné dans les propriétés de la classe TimeManager
  5. Mettre en œuvre la transition d'écran entre l'écran de réglage et la liste des sons d'alarme

1. Examiner les éléments (propriété) requis pour la structure sonore de l'alarme

À ce stade, le son de l'alarme est spécifié par défaut et ne peut pas être modifié. Nous préparerons quelques sons d'alarme et les rendrons modifiables à partir de l'écran de réglage.

Compte tenu des éléments nécessaires en tant qu'objet sonore d'alarme, les deux suivants sont suffisants.

2. Créez une structure sonore d'alarme dans les données

Créez une structure nommée Sound dans votre fichier Data.swift et incluez les deux éléments considérés à l'étape 1 comme ses propriétés.

À ce stade, le type de données de la propriété Sound ID doit être SystemSoundID. Ce type de données est inclus dans la bibliothèque AudioToolbox, assurez-vous donc de l'importer.

Il hérite du protocole Identifiable car l'ID de son requiert que l'instance créée à partir de cette structure soit unique.

Data.swift


import SwiftUI
import AudioToolbox //Importation supplémentaire

//(Autre énumération omise)

struct Sound: Identifiable {
    let id: SystemSoundID
    let soundName: String
}

3.Faites une liste des sons d'alarme

Créez un nouveau fichier Swift nommé SoundListView à partir du modèle SwiftUI. Importez la bibliothèque AudioToolbox pour utiliser le son système.

Comme toute autre vue, nous voulons toujours voir les propriétés de la classe TimeManager, alors créez-en une instance. Préfixe var avec le wrapper de propriété @EnvironmentObject.

SoundListView


import SwiftUI
import AudioToolbox

struct SoundListView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    var body: some View {
        Text("Hello, World!")
    }
}

Ensuite, préparez les données sonores de l'alarme.

Créez une instance à partir de la structure Sound créée à l'étape 1, en spécifiant les propriétés id et soundName, et stockez-la dans un tableau nommé Sounds. Reportez-vous aux ressources suivantes pour l'ID de son spécifique. Rendez soundName facile à comprendre en faisant référence au nom de fichier dans la ressource. https://github.com/TUNER88/iOSSystemSoundsLibrary

SoundListView


struct SoundListView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    let sounds: [Sound] = [
        Sound(id: 1151, soundName: "Beat"),
        Sound(id: 1304, soundName: "Alert"),
        Sound(id: 1309, soundName: "Glass"),
        Sound(id: 1310, soundName: "Horn"),
        Sound(id: 1313, soundName: "Bell"),
        Sound(id: 1314, soundName: "Electronic"),
        Sound(id: 1320, soundName: "Anticipate"),
        Sound(id: 1327, soundName: "Minuet"),
        Sound(id: 1328, soundName: "News Flash"),
        Sound(id: 1330, soundName: "Sherwood Forest"),
        Sound(id: 1333, soundName: "Telegraph"),
        Sound(id: 1334, soundName: "Tiptoes"),
        Sound(id: 1335, soundName: "Typewriterst"),
        Sound(id: 1336, soundName: "Update")
    ]

    var body: some View {
        Text("Hello, World!")
    }
}

Préparez la liste {} dans le cadre le plus à l'extérieur du corps {}. Cette liste est similaire au formulaire utilisé dans SettingView et est utilisée pour afficher de nombreux éléments au format tabulaire séparés par des bordures.

ForEach est utile lorsque vous souhaitez classer les éléments d'un tableau dans une liste {}. En définissant ForEach (sons), les éléments des sons seront mis en boucle dans l'ordre. Le contenu du traitement est décrit dans {}.

Tout d'abord, écrivez le nom du son sous forme de texte en {}.

SoundListView


struct SoundListView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    let sounds: [Sound] = [
        //(Chaque objet sonore est omis)
    ]

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Affichage dans la liste par la valeur de soundName
                Text(("\(sound.soundName)"))
            }
        }
    }
}

4. Autoriser le son de l'alarme à être auditionné

En tant qu'opération réelle de l'application, je souhaite vérifier le type de son émis lors de la sélection d'une alarme.

Nous afficherons l'icône d'audition à l'extrémité gauche de chaque ligne de la liste et la toucherons pour jouer le son.

Ajoutez HStack {} à l'intérieur de ForEach {} afin que les composants soient côte à côte sur chaque ligne.

Au tout début de HStack {}, ajoutez un composant Image en tant qu'icône. J'ai choisi "speaker.2.fill" de SF Symbols. Ajoutez ensuite le modificateur .onTapGesture {} et écrivez la méthode de bibliothèque AudioToolbox AudioServicesPlayAlertSoundWithCompletion () dans la fermeture {}. En définissant l'argument sur sound.id, l'identifiant de la ligne tapée est choisi comme soundID et lu. Le deuxième argument peut être nul.

SoundListView


struct SoundListView: View {
    //(Propriété omise)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Description d'une ligne dans la liste
                HStack {
                    //Icône d'audition
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //Affichage dans la liste par la valeur de soundName
                    Text(("\(sound.soundName)"))
                }
            }
        }
        .navigationBarTitle("Alarm Sound Setting", displayMode: .automatic)
    }
}

5. Refléter le son d'alarme sélectionné dans les propriétés de la classe TimeManager

Appuyez sur une ligne pour sélectionner ce son.

Plus précisément, HStack {} correspond à une ligne dans la liste, alors ajoutez .onTapGesture {} comme modificateur. Dans la fermeture {} de .onTapGesture {}, l'ID et le nom du son de la ligne sélectionnée sont respectivement affectés à la propriété soundID et à la propriété soundName déjà préparées de la classe TimeManager.

Cependant, avec cela seul, vous ne pouvez le sélectionner qu'en touchant l'affichage du nom du son dans la liste des sons. Il n'y a pas de réponse même si vous appuyez sur la partie vide de la ligne. C'est bien, mais je vais le réparer ici aussi.

Ajoutez .contentShape (Rectangle ()) avant .onTapGesture {} comme modificateur pour HStack. Cela permet à HStack d'être considéré comme un objet carré, c'est-à-dire que la ligne entière devient un objet unique, et vous pouvez appuyer sur une zone vide pour sélectionner le son d'alarme.

SoundListView


struct SoundListView: View {
    //(Propriété omise)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Description d'une ligne dans la liste
                HStack {
                    //Icône d'audition
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //Affichage dans la liste par la valeur de soundName
                    Text(("\(sound.soundName)"))
                }
                //Pensez à HStack comme un objet carré
                .contentShape(Rectangle())
                //Appuyez sur une ligne pour sélectionner un son (refléter l'ID et le nom dans TimeManager)
                .onTapGesture {
                    self.timeManager.soundID = sound.id
                    self.timeManager.soundName = sound.soundName
                }
            }
        }
    }
}

De plus, la syntaxe if est utilisée pour qu'une coche apparaisse à droite du nom du son actuellement sélectionné. Je veux que la coche soit à l'extrême droite de la ligne, alors placez Spacer () entre le nom du son et la coche.

SoundListView


struct SoundListView: View {
    //(Propriété omise)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Description d'une ligne dans la liste
                HStack {
                    //Icône d'audition
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //Affichage dans la liste par la valeur de soundName
                    Text(("\(sound.soundName)"))
                    
                    Spacer()
                    
                    //Affiche une coche pour le son actuellement sélectionné
                    if self.timeManager.soundID == sound.id {
                        Image(systemName: "checkmark")
                    }
                }
                //Pensez à HStack comme un objet carré
                .contentShape(Rectangle())
                //Appuyez sur une ligne pour sélectionner un son (refléter l'ID et le nom dans TimeManager)
                .onTapGesture {
                    self.timeManager.soundID = sound.id
                    self.timeManager.soundName = sound.soundName
                }
            }
        }
    }
}

Vérifiez le SoundListView dans Canvas. Vous trouverez ci-dessous le code de l'aperçu.

struct SoundListView_Previews: PreviewProvider {
    static var previews: some View {
        SoundListView()
            .environmentObject(TimeManager())
    }
}
スクリーンショット 2020-10-28 11.04.57.png

6. Mettre en œuvre la transition d'écran entre l'écran de réglage et la liste des sons d'alarme

Ajoutez un élément de sélection de son d'alarme à l'écran de réglage principal SettingView afin qu'il passe à l'écran de la liste sonore SoundListView.

La partie la plus externe du corps SettingView {} est entourée par NavigationView {}. Cela vous permet de déplacer l'écran au niveau suivant en ajoutant NavigationLink {} à l'intérieur du formulaire {}.

Réglez le nom de l'élément de réglage sur "Sélection du son" avec Texte (), placez l'espacement () entre les deux pour que le nom du son d'alarme actuellement sélectionné s'affiche à l'extrémité droite de la ligne, et utilisez Texte () pour TimeManager. Spécifie la propriété de classe soundName.

Ajoutez les deux modificateurs de formulaire suivants pour spécifier l'affichage de NavigationBar (en haut de l'écran) et le style d'affichage de l'ensemble de NavigationView.

.navigationBarTitle() .navigationViewStyle()

SettingView.swift


struct SettingView: View {
    //(Propriété omise)
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Alarm:")) {
                    Toggle(isOn: $timeManager.isAlarmOn) {
                        Text("Alarm Sound")
                    }
                    Toggle(isOn: $timeManager.isVibrationOn) {
                        Text("Vibration")
                    }
                    //Transition de l'écran vers l'écran de sélection du son
                    NavigationLink(destination: SoundListView()) {
                        HStack {
                            //Nom de l'élément de réglage
                            Text("Sound Selection")
                            Spacer()
                            //Son d'alarme actuellement sélectionné
                            Text("\(timeManager.soundName)")
                        }
                    }
                }
                Section(header: Text("Animation:")) {
                    //(Le contenu de la section Animation est omis)
                }
                Section(header: Text("Save:")) {
                    //(Le contenu de la section Enregistrer est omis)
                }
            }
            .navigationBarTitle("Setting", displayMode: .automatic)
            .navigationViewStyle(DefaultNavigationViewStyle())
        }
    }
}

Ensuite, ajoutez le modificateur .navigationBarTitle à List {} de SoundListView et donnez le titre d'écran "Alarm Sound Setting".

SoundListView


struct SoundListView: View {
    //(Propriété omise)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Description d'une ligne dans la liste
                HStack {
                    //Icône d'audition
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //Affichage dans la liste par la valeur de soundName
                    Text(("\(sound.soundName)"))
                    
                    Spacer()
                    
                    //Affiche une coche pour le son actuellement sélectionné
                    if self.timeManager.soundID == sound.id {
                        Image(systemName: "checkmark")
                    }
                }
                //Appuyez sur une ligne pour sélectionner un son (refléter l'ID et le nom dans TimeManager)
                .onTapGesture {
                    self.timeManager.soundID = sound.id
                    self.timeManager.soundName = sound.soundName
                }
            }
        }
        .navigationBarTitle("Alarm Sound Setting", displayMode: .automatic)
    }
}

Ceci termine la mise en œuvre de l'écran de réglage, y compris la sélection du son d'alarme. Vérifiez le SettingView sur Canvas. Cela devrait ressembler à l'image ci-dessous. スクリーンショット 2020-10-28 11.08.56.png

La prochaine fois, je publierai sur la mise en œuvre d'une barre de progression visuellement agréable.

Recommended Posts

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 (8. Implémentation de la barre de progression)
Développement d'applications iOS: application Timer (4. Implémentation du compte à rebours)
Développement d'applications iOS: application Timer (6. Création de l'écran de réglage)
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 (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 (9. Personnalisez la couleur de la barre de progression)
Développement d'applications iOS: application Timer (3. bouton Démarrer / Arrêter, bouton Réinitialiser)
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)
Mémo d'implémentation SKStoreReviewController dans l'interface utilisateur Swift d'iOS14