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.
Sie können den Beispielcode unter der folgenden Git-Repository-URL sehen. https://github.com/msnsk/Qiita_Timer.git
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)
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
}
}
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 {
}
}
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()
}
}
}
}
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.
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.
Nächstes Mal werden wir eine Countdown-Anzeige der verbleibenden Zeit implementieren.
Recommended Posts