[SWIFT] iOS App Entwicklung: Timer App (7. Implementierung der Alarmtonauswahl)

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

Inhalt

Die Punkte zum Erstellen einer Timer-App werden in mehreren Artikeln veröffentlicht. In diesem Artikel werde ich über die Implementierung des Alarmton-Auswahlbildschirms berichten.

Umgebung

Git-Repository

Sie können den Beispielcode unter der folgenden Git-Repository-URL sehen. https://github.com/msnsk/Qiita_Timer.git

Verfahren

  1. Untersuchen Sie die Elemente (Eigenschaften), die für die Alarmtonstruktur erforderlich sind
  2. Erstellen Sie einen Alarmton Struct in Data
  3. Erstellen Sie eine Liste mit Alarmtönen
  4. Lassen Sie den Alarmton abhören
  5. Reflektieren Sie den ausgewählten Alarmton in den Eigenschaften der TimeManager-Klasse
  6. Implementieren Sie den Bildschirmübergang zwischen Einstellungsbildschirm und Alarmtonliste

1. Untersuchen Sie die Elemente (Eigenschaften), die für die Alarmtonstruktur erforderlich sind

Zu diesem Zeitpunkt ist der Alarmton standardmäßig festgelegt und kann nicht geändert werden. Wir werden einige Alarmtöne vorbereiten und diese über den Einstellungsbildschirm ändern.

In Anbetracht der Elemente, die als Alarmtonobjekt erforderlich sind, sind die folgenden beiden ausreichend.

--Sound ID: Erforderlich, um einen Sound mit einer Methode in der AudioToolbox-Bibliothek abzuspielen

2. Erstellen Sie einen Alarmton Struct in Data

Erstellen Sie eine Struktur mit dem Namen Sound in Ihrer Data.swift-Datei und fügen Sie die beiden in Schritt 1 berücksichtigten Elemente als Eigenschaften hinzu.

Zu diesem Zeitpunkt muss der Datentyp der Sound-ID-Eigenschaft SystemSoundID sein. Dieser Datentyp ist in der AudioToolbox-Bibliothek enthalten. Importieren Sie ihn daher unbedingt.

Es erbt das identifizierbare Protokoll, da für die Sound-ID die aus dieser Struktur erstellte Instanz eindeutig sein muss.

Data.swift


import SwiftUI
import AudioToolbox //Zusätzlicher Import

//(Andere Aufzählung weggelassen)

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

3. Erstellen Sie eine Liste mit Alarmtönen

Erstellen Sie eine neue Swift-Datei mit dem Namen SoundListView aus der SwiftUI-Vorlage. Importieren Sie die AudioToolbox-Bibliothek, um den Systemton zu verwenden.

Wie bei jeder anderen Ansicht möchten wir immer die Eigenschaften der TimeManager-Klasse anzeigen. Erstellen Sie daher eine Instanz davon. Präfix var mit dem Eigenschafts-Wrapper @EnvironmentObject.

SoundListView


import SwiftUI
import AudioToolbox

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

Bereiten Sie als Nächstes die Alarmtondaten vor.

Erstellen Sie eine Instanz aus der in Schritt 1 erstellten Sound-Struktur, geben Sie die Eigenschaften id und soundName an und speichern Sie sie in einem Array mit dem Namen Sounds. Informationen zur spezifischen Sound-ID finden Sie in den folgenden Ressourcen. Machen Sie soundName leicht verständlich, indem Sie auf den Dateinamen in der Ressource verweisen. 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!")
    }
}

Bereiten Sie die Liste {} im äußersten Rahmen innerhalb des Körpers {} vor. Diese Liste ähnelt dem in SettingView verwendeten Formular und wird verwendet, um viele Elemente in tabellarischem Format anzuzeigen, die durch Rahmen getrennt sind.

ForEach ist nützlich, wenn Sie die Elemente in einem Array in einer Liste {} bestellen möchten. Durch Einstellen von ForEach (Sounds) werden die Elemente in Sounds in der angegebenen Reihenfolge wiederholt. Der Verarbeitungsinhalt ist in {} beschrieben.

Schreiben Sie zuerst den Soundnamen als Text in {}.

SoundListView


struct SoundListView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    let sounds: [Sound] = [
        //(Jedes Klangobjekt weggelassen)
    ]

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //In der Liste nach dem Wert von soundName anzeigen
                Text(("\(sound.soundName)"))
            }
        }
    }
}

4. Lassen Sie den Alarmton abhören

Als tatsächlicher Vorgang der App möchte ich überprüfen, welche Art von Ton bei der Auswahl eines Alarms ertönt.

Wir werden das Audition-Symbol am linken Ende jeder Zeile der Liste anzeigen und darauf tippen, um den Sound abzuspielen.

Fügen Sie HStack {} in ForEach {} hinzu, sodass die Komponenten in jeder Zeile nebeneinander liegen.

Fügen Sie ganz am Anfang von HStack {} eine Bildkomponente als Symbol hinzu. Ich habe "Speaker.2.fill" von SF Symbols gewählt. Fügen Sie dann den Modifikator .onTapGesture {} hinzu und schreiben Sie die AudioToolbox-Bibliotheksmethode AudioServicesPlayAlertSoundWithCompletion () in den Abschluss {}. Durch Setzen des Arguments auf sound.id wird die ID der abgegriffenen Zeile als soundID aufgenommen und abgespielt. Das zweite Argument kann Null sein.

SoundListView


struct SoundListView: View {
    //(Eigentum weggelassen)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Beschreibung einer Zeile in der Liste
                HStack {
                    //Audition-Symbol
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //In der Liste nach dem Wert von soundName anzeigen
                    Text(("\(sound.soundName)"))
                }
            }
        }
        .navigationBarTitle("Alarm Sound Setting", displayMode: .automatic)
    }
}

5. Reflektieren Sie den ausgewählten Alarmton in den Eigenschaften der TimeManager-Klasse

Tippen Sie auf eine Zeile, um diesen Sound auszuwählen.

Insbesondere entspricht HStack {} einer Zeile in der Liste. Fügen Sie daher .onTapGesture {} als Modifikator hinzu. Beim Schließen {} von .onTapGesture {} werden die Sound-ID und der Soundname der ausgewählten Zeile der bereits vorbereiteten Eigenschaft soundID bzw. soundName der TimeManager-Klasse zugewiesen.

Sie können es jedoch nur auswählen, indem Sie auf die Anzeige des Soundnamens in der Soundliste tippen. Es erfolgt keine Antwort, selbst wenn Sie auf den leeren Teil der Zeile tippen. Es ist in Ordnung, aber ich werde es auch hier beheben.

Fügen Sie vor .onTapGesture {} .contentShape (Rectangle ()) als Modifikator für HStack hinzu. Auf diese Weise kann der HStack als quadratisches Objekt betrachtet werden, dh die gesamte Zeile wird zu einem einzelnen Objekt, und Sie können auf einen leeren Bereich tippen, um den Alarmton auszuwählen.

SoundListView


struct SoundListView: View {
    //(Eigentum weggelassen)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Beschreibung einer Zeile in der Liste
                HStack {
                    //Audition-Symbol
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //In der Liste nach dem Wert von soundName anzeigen
                    Text(("\(sound.soundName)"))
                }
                //Stellen Sie sich HStack als quadratisches Objekt vor
                .contentShape(Rectangle())
                //Tippen Sie auf eine Linie, um einen Sound auszuwählen (ID und Name in TimeManager wiedergeben).
                .onTapGesture {
                    self.timeManager.soundID = sound.id
                    self.timeManager.soundName = sound.soundName
                }
            }
        }
    }
}

Außerdem wird die if-Syntax verwendet, sodass rechts neben dem aktuell ausgewählten Soundnamen ein Häkchen angezeigt wird. Ich möchte, dass sich das Häkchen ganz rechts in der Zeile befindet. Setzen Sie also Spacer () zwischen den Soundnamen und das Häkchen.

SoundListView


struct SoundListView: View {
    //(Eigentum weggelassen)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Beschreibung einer Zeile in der Liste
                HStack {
                    //Audition-Symbol
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //In der Liste nach dem Wert von soundName anzeigen
                    Text(("\(sound.soundName)"))
                    
                    Spacer()
                    
                    //Zeigen Sie ein Häkchen für den aktuell ausgewählten Sound an
                    if self.timeManager.soundID == sound.id {
                        Image(systemName: "checkmark")
                    }
                }
                //Stellen Sie sich HStack als quadratisches Objekt vor
                .contentShape(Rectangle())
                //Tippen Sie auf eine Linie, um einen Sound auszuwählen (ID und Name in TimeManager wiedergeben).
                .onTapGesture {
                    self.timeManager.soundID = sound.id
                    self.timeManager.soundName = sound.soundName
                }
            }
        }
    }
}

Überprüfen Sie die SoundListView in Canvas. Unten ist der Code für die Vorschau.

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

6. Implementieren Sie den Bildschirmübergang zwischen Einstellungsbildschirm und Alarmtonliste

Fügen Sie dem Haupteinstellungsbildschirm SettingView ein Alarmtonauswahlelement hinzu, damit es zum Soundlistenbildschirm SoundListView übergeht.

Der äußerste Teil des SettingView-Körpers {} ist von NavigationView {} umgeben. Auf diese Weise können Sie den Bildschirm auf die nächste Ebene verschieben, indem Sie NavigationLink {} im Formular {} hinzufügen.

Setzen Sie den Namen des Einstellungselements mit Text () auf "Sound Selection", setzen Sie Spacer () dazwischen, damit der Name des aktuell ausgewählten Alarmtons am rechten Ende der Zeile angezeigt wird, und verwenden Sie Text () für TimeManager. Gibt die Klasseneigenschaft soundName an.

Fügen Sie die folgenden zwei Formularmodifikatoren hinzu, um die Anzeige der Navigationsleiste (oben auf dem Bildschirm) und den Anzeigestil der gesamten Navigationsansicht festzulegen.

.navigationBarTitle() .navigationViewStyle()

SettingView.swift


struct SettingView: View {
    //(Eigentum weggelassen)
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Alarm:")) {
                    Toggle(isOn: $timeManager.isAlarmOn) {
                        Text("Alarm Sound")
                    }
                    Toggle(isOn: $timeManager.isVibrationOn) {
                        Text("Vibration")
                    }
                    //Bildschirmübergang zum Tonauswahlbildschirm
                    NavigationLink(destination: SoundListView()) {
                        HStack {
                            //Elementnamen einstellen
                            Text("Sound Selection")
                            Spacer()
                            //Derzeit ausgewählter Alarmton
                            Text("\(timeManager.soundName)")
                        }
                    }
                }
                Section(header: Text("Animation:")) {
                    //(Der Inhalt des Animationsabschnitts wird weggelassen.)
                }
                Section(header: Text("Save:")) {
                    //(Der Inhalt des Abschnitts Speichern wird weggelassen.)
                }
            }
            .navigationBarTitle("Setting", displayMode: .automatic)
            .navigationViewStyle(DefaultNavigationViewStyle())
        }
    }
}

Fügen Sie dann den Modifikator .navigationBarTitle zur Liste {} von SoundListView hinzu und geben Sie den Bildschirmtitel "Alarm Sound Setting" ein.

SoundListView


struct SoundListView: View {
    //(Eigentum weggelassen)

    var body: some View {
        List {
            ForEach(sounds) {sound in
                //Beschreibung einer Zeile in der Liste
                HStack {
                    //Audition-Symbol
                    Image(systemName: "speaker.2.fill")
                        .onTapGesture {
                            AudioServicesPlayAlertSoundWithCompletion(sound.id, nil)
                    }           
                    //In der Liste nach dem Wert von soundName anzeigen
                    Text(("\(sound.soundName)"))
                    
                    Spacer()
                    
                    //Zeigen Sie ein Häkchen für den aktuell ausgewählten Sound an
                    if self.timeManager.soundID == sound.id {
                        Image(systemName: "checkmark")
                    }
                }
                //Tippen Sie auf eine Linie, um einen Sound auszuwählen (ID und Name in TimeManager wiedergeben).
                .onTapGesture {
                    self.timeManager.soundID = sound.id
                    self.timeManager.soundName = sound.soundName
                }
            }
        }
        .navigationBarTitle("Alarm Sound Setting", displayMode: .automatic)
    }
}

Damit ist die Implementierung des Einstellungsbildschirms einschließlich der Auswahl des Alarmtons abgeschlossen. Überprüfen Sie die SettingView auf Canvas. Es sollte wie im Bild unten aussehen. スクリーンショット 2020-10-28 11.08.56.png

Das nächste Mal werde ich über die Implementierung eines visuell ansprechenden Fortschrittsbalkens berichten.

Recommended Posts

iOS App Entwicklung: Timer App (7. Implementierung der Alarmtonauswahl)
iOS App Entwicklung: Timer App (5. Implementierung von Alarm und Vibration)
iOS App Entwicklung: Timer App (8. Implementierung des Fortschrittsbalkens)
iOS App Entwicklung: Timer App (4. Implementierung des Countdowns)
iOS App Entwicklung: Timer App (6. Erstellung des Einstellungsbildschirms)
iOS App Entwicklung: Timer App (2. Timer Anzeige)
iOS App Entwicklung: Timer App (Zusammenfassung)
iOS App Entwicklung: Timer App (1. Timer Zeiteinstellung)
iOS App Entwicklung: Timer App (10. Animation erstellen)
Entwicklung der iOS-App: Timer-App (9. Passen Sie die Farbe des Fortschrittsbalkens an)
Entwicklung der iOS-App: Timer-App (3. Start / Stopp-Taste, Reset-Taste)
Komplettes IOS-App-Entwicklungstagebuch zum Selbststudium
Roadmap für die Entwicklung von iOS-Apps (Einführung)
Implementierungsnotiz für SKStoreReviewController in der Swift-Benutzeroberfläche von iOS14