[SWIFT] Entwicklung der iOS-App: Timer-App (3. Start / Stopp-Taste, Reset-Taste)

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

Inhalt

Die Punkte zum Erstellen einer Timer-App werden in mehreren Artikeln veröffentlicht. In diesem Artikel werde ich die Schritte zum Implementieren der Start-, Pausen- und Rücksetzfunktionen veröffentlichen, die die Hauptoperationen des Countdown-Timers sind.

Umgebung

Git-Repository

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

Verfahren

  1. Erstellen Sie in TimeManager eine Eigenschaft, die den Status des Timers angibt
  2. Erstellen Sie in TimeManager eine Methode, um den Status des Timers zu ändern
  3. Erstellen Sie ButtonsView
  4. Erstellen Sie eine Start / Stopp-Schaltfläche in ButtonsView
  5. Erstellen Sie in ButtonsView eine Reset-Schaltfläche
  6. Platzieren Sie ButtonsView in MainView

1. Erstellen Sie in TimeManager eine Eigenschaft, die den Status des Timers angibt

Erstellen Sie eine Eigenschaft in der TimeManager-Klasse, die den Status des Timers darstellt. Der Status ist die folgenden drei.

--running: Der Timer läuft herunter --pause: Der Timer ist angehalten und kann fortgesetzt werden --stop: Der Zustand, in dem der Timer den Countdown beendet hat

Erstellen Sie zur Vorbereitung eine neue Aufzählung in der Datei Data.swift, die den Status des Timers darstellt.

Data.swift


//(Andere Aufzählung weggelassen)

enum TimerStatus {
    case running
    case pause
    case stopped
}

Erstellen Sie eine Eigenschaft in der TimeManager-Klasse mit der erstellten Aufzählung als Datentyp. Der Standardwert für diese Eigenschaft sollte gestoppt sein, da der Timer inaktiv sein muss, bis der Benutzer auf die Startschaltfläche tippt.

TimeManager.swift


class TimeManager: ObservableObject {
    //(Andere Eigenschaften weggelassen)

    //Timer-Status
    @Published var timerStatus: TimerStatus = .stopped

    //(Methode weggelassen)

2. Erstellen Sie in TimeManager eine Methode, um den Status des Timers zu ändern

Wir haben noch keine Schaltflächen erstellt, aber wir erstellen Methoden zum Starten, Anhalten und vollständigen Beenden des Timers, wenn Sie zuerst auf die einzelnen Schaltflächen tippen. Mit anderen Worten, diese Methoden ändern den Wert der Timer-Statuseigenschaft, die jedes Mal früher erstellt wurde.

TimeManager.swift


class TimeManager: ObservableObject {
    //(Eigentum weggelassen)

    //(Andere Methoden weggelassen)

    //Methode, die aktiviert wird, wenn die Starttaste gedrückt wird
    func start() {
        //Timer-Status.auf Laufen eingestellt
        timerStatus = .running
    }
    
    //Methode, die aktiviert wird, wenn die Pause-Taste gedrückt wird
    func pause() {
        //Timer-Status.Pause
        timerStatus = .pause
    }
    
    //Methode, die aktiviert wird, wenn die Reset-Taste gedrückt wird
    func reset() {
        //Timer-Status.Halt
        timerStatus = .stopped
        //Zwangsweise auf 0 setzen, auch wenn die verbleibende Zeit noch nicht 0 ist
        duration = 0
    }
}

3. Erstellen Sie ButtonsView

Erstellen Sie eine neue Datei mit dem Namen ButtonsView.swift. Eine gleichnamige Struktur wird generiert.

Da die Schaltflächenoperation mit der timerStatus-Eigenschaft der in Schritt 1 erstellten TimeManager-Klasse verknüpft werden muss, erstellen Sie auch in dieser Ansicht eine Instanz der TimeManager-Klasse. Wie üblich werde ich auch einen Eigenschafts-Wrapper für @EnvironmentObject hinzufügen.

ButtonsView.swift


import SwiftUI
    @EnvironmentObject var timeManager: TimeManager

struct ButtonsView: View {
    var body: some View {

    }
}

4. Erstellen Sie eine Start / Stopp-Schaltfläche in ButtonsView

Die Starttaste und die Stopptaste werden an derselben Stelle auf dem Bildschirm angezeigt. Abhängig vom Timer-Status ist es bedingt, welche Schaltfläche auf dem Bildschirm angezeigt wird.

Die folgenden zwei Schaltflächensymbole von echten Apple SF-Symbolen werden verwendet (üblicherweise zum Abspielen und Anhalten von Audio).

--play.circle.fill: Startschaltfläche --pause.circle.fill: Pause-Taste

Wenn die Anzeige der verbleibenden Zeit 0 ist, bedeutet dies, dass Sie nicht starten oder anhalten können. Erstellen Sie daher eine bedingte Verzweigung mit dem Modifikator Transparenz .opacity.

Geben Sie die setTimer-Methode so an, dass beim Tippen auf die Schaltfläche die PickerView angezeigt wird (und die Zeit eingestellt ist). Durch Tippen auf die Schaltfläche Start wird der Timer eingestellt. Wenn die PickerView angezeigt wird, wird der Timer-Status gestoppt. Schreiben Sie dies daher mit einer if-Anweisung in den Modifikator onTapGesture.

Wenn diese setTimer-Methode durch Tippen auf die Schaltfläche ausgeführt wird, wird die in der Eigenschaft duration der verbleibenden Zeit und der Eigenschaft maxValue der maximalen Zeit festgelegte Zeit zugewiesen. Schreiben Sie eine if-Anweisung in den Modifikator onTapGesture, damit die Startmethode auch ausgeführt wird, wenn diese Dauer ungleich Null ist und der Timer-Status nicht ausgeführt wird.

Als weitere Bedingung folgt auf die if-Anweisung die if else-Anweisung, sodass sie nur angehalten werden kann, wenn der Timer-Status .running lautet.

ButtonsView.swift


struct ButtonsView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    var body: some View {
        //running:Pause-Taste/pause or stopped:Start Knopf
        Image(systemName: self.timeManager.timerStatus == .running ? "pause.circle.fill" : "play.circle.fill")
            .resizable()
            .aspectRatio(contentMode: .fit)
            .frame(width: 75, height: 75)
            //Platz auf der rechten Seite der Schaltfläche und am Rand des Bildschirms
            .padding(.trailing)
            //Wenn die Stunden, Minuten und Sekunden des Pickers alle 0 sind, wird die Transparenz der Schaltfläche auf 0 gesetzt..1 zu 1 sonst (undurchsichtig)
            .opacity(self.timeManager.hourSelection == 0 && self.timeManager.minSelection == 0 && self.timeManager.secSelection == 0 ? 0.1 : 1)
            //Aktion beim Tippen auf eine Schaltfläche
            .onTapGesture {
                if timeManager.timerStatus == .stopped {
                    self.timeManager.setTimer()
                }
                //Die verbleibende Zeit ist ungleich Null und der Timer-Status ist.Anders als Laufen
                if timeManager.duration != 0 && timeManager.timerStatus != .running {
                    self.timeManager.start()
                //Der Timer-Status ist.Zum Laufen
                } else if timeManager.timerStatus == .running {
                    self.timeManager.pause()
                }
            }
    }
}

5. Erstellen Sie in ButtonsView eine Reset-Schaltfläche

Erstellen Sie weitere Reset-Schaltflächen in der ButtonsView.

Tippen Sie auf diese Schaltfläche, um die in Schritt 2 erstellte Rücksetzmethode der TimeManager-Klasse auszulösen.

Für das Schaltflächensymbol haben wir "stop.circle.fill" von SF Symbols übernommen.

Schreiben Sie eine if-Anweisung in den Modifikator onTapGesture, damit die Reset-Methode ausgelöst wird, wenn der Timer-Status nicht .stopped ist.

In Bezug auf das Tastenlayout möchte ich die Reset-Taste auf der linken Seite des Bildschirms und die zuvor erstellte Start- / Pause-Taste auf der rechten Seite des Bildschirms platzieren. Platzieren Sie also beide Tasten im HStack.

Wenn die Standardeinstellung beibehalten wird, werden beide Schaltflächen auf dem Bildschirm zentriert. Fügen Sie daher einen Abstandhalter zwischen die Schaltflächen ein, sodass sich die Schaltflächen auf beiden Seiten des Bildschirms befinden.

Wenn Sie die Schaltfläche zu nahe an den Bildschirmrand bewegen, sieht sie schlecht aus, daher habe ich sie mit Polsterung angepasst.

ButtonsView.swift


struct ButtonsView: View {
    @EnvironmentObject var timeManager: TimeManager
    
    var body: some View {
        //Die Reset-Taste links auf dem Bildschirm in HStack beginnt rechts/Pause-Taste
        HStack {
            //Reset-Knopf
            Image(systemName: "stop.circle.fill")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: 75, height: 75)
                //Lassen Sie auf der linken Seite der Schaltfläche und am Rand des Bildschirms Platz
                .padding(.leading)
                //Transparenz 0, wenn der Timer-Status endet.Zu 1, sonst undurchsichtig
                .opacity(self.timeManager.timerStatus == .stopped ? 0.1 : 1)
                //Aktion beim Tippen auf eine Schaltfläche
                .onTapGesture {
                    //Der Timer-Status ist.Anders als gestoppt
                    if timeManager.timerStatus != .stopped {
                    self.timeManager.reset()
                }
            
            //Abstand zwischen den Tasten
            Spacer()
            
            //running:Pause-Taste/pause or stopped:Start Knopf
            Image(systemName: self.timeManager.timerStatus == .running ? "pause.circle.fill" : "play.circle.fill")
                //(Modifikator weggelassen)
        } 
    }
}

Mal sehen, wie die ButtonsView auf Canvas aussieht. Unten ist der Code für die Vorschau.

struct ButtonsView_Previews: PreviewProvider {
    static var previews: some View {
        ButtonsView()
            .environmentObject(TimeManager())
            .previewLayout(.sizeThatFits)
    }
}

Es sieht aus wie auf dem Bild unten. Da der Anfangswert des Timer-Status gestoppt ist, wird die Schaltfläche abgeblendet und beim Tippen als nicht reagierend angezeigt. スクリーンショット 2020-10-28 10.32.02.png

6. Platzieren Sie ButtonsView in MainView

PickerView und TimerView wurden bereits zu MainView hinzugefügt.

Schreiben Sie eine if-else-Anweisung, damit die angezeigte Ansicht davon abhängt, ob der Timer-Status gestoppt ist.

PickerView und TimerView sind die beiden wichtigsten Komponenten dieser Timer-App. Sie sollten daher auf dem Bildschirm zentriert sein (sofern Sie keine Platzierung angeben, werden sie standardmäßig horizontal und vertikal zentriert).

In Anbetracht der Bedienung mit dem Finger eines iOS-Geräts wie iPhone möchte ich die ButtonsView, die ich dieses Mal hinzufügen möchte, unter PickerView / TimerView und auch nahe am unteren Bildschirmrand platzieren, sodass ich ZStack zu einer separaten Ebene von PickerView / TimerView und VStack gemacht habe Bewegen Sie die ButtonsView nach unten, indem Sie einen Abstandshalter über der ButtonsView platzieren. Am Rand des Bildschirms sieht es jedoch nicht gut aus. Nehmen Sie daher Feineinstellungen mit dem Modifikator "Auffüllen" (.bottom) vor.

MainView.swift


struct MainView: View {
    @EnvironmentObject var timeManager: TimeManager
    
     var body: some View {
        ZStack {
            if timeManager.timerStatus == .stopped {
                PickerView()
            } else {
                TimerView()
            }
            
            VStack {
                Spacer()
                ButtonsView()
                    .padding(.bottom)
            }
        }
        
    }
}

Überprüfen Sie die Anzeige von MainView auf Leinwand. Code für die Vorschau.

struct MainView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            MainView().environmentObject(TimeManager())
        }
    }
}

Da der Anfangswert des Timer-Status gestoppt ist, zeigt der bedingte Zweig der if-Anweisung nur PickerView an und verbirgt die überlappende TimerView in ZStack. ButtonsView wird von Spacer in VStack gepusht und befindet sich am unteren Bildschirmrand. スクリーンショット 2020-10-28 10.32.20.png

Nächstes Mal werden wir eine Countdown-Anzeige der verbleibenden Zeit implementieren.

Recommended Posts

Entwicklung der iOS-App: Timer-App (3. Start / Stopp-Taste, Reset-Taste)
iOS App Entwicklung: Timer App (Zusammenfassung)
iOS App Entwicklung: Timer App (4. Implementierung des Countdowns)
iOS App Entwicklung: Timer App (1. Timer Zeiteinstellung)
iOS App Entwicklung: Timer App (10. Animation erstellen)
iOS App Entwicklung: Timer App (6. Erstellung des Einstellungsbildschirms)
iOS App Entwicklung: Timer App (8. Implementierung des Fortschrittsbalkens)
iOS App Entwicklung: Timer App (7. Implementierung der Alarmtonauswahl)
iOS App Entwicklung: Timer App (5. Implementierung von Alarm und Vibration)
Komplettes IOS-App-Entwicklungstagebuch zum Selbststudium
Roadmap für die Entwicklung von iOS-Apps (Einführung)