当计时器停止swiftUI Apple Watch时发出声音



我目前正在为Apple Watch开发计时器应用程序。当计时器达到5秒时,我设法发出声音。只是,当我按下"完成"时,计时器的声音仍然会播放,我现在不知道如何停止声音。我正在使用WKInterfaceDevice.current((.play(.success(.

我想在5秒内按下"取消"按钮和按下"完成"按钮时停止声音。

我在网上找不到任何东西。我认为WKInterfaceDevice没有停止功能。

struct softView: View {
@State var timerVal = 10
var body: some View {
VStack {
if timerVal > 0 {
Text("Time Remaining")
.font(.system(size: 14))
Text("(timerVal)")
.font(.system(size: 40))
.onAppear(){
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
if self.timerVal > 0 {
self.timerVal -= 1
}
if self.timerVal < 6 {
WKInterfaceDevice.current().play(.success)
}
}
}
Text("Seconds")
.font(.system(size: 14))
Divider()
Spacer()
NavigationLink(destination: ContentView(), label: {Text("Cancel")})
//.cornerRadius(20)
.foregroundColor(Color.red)
.background(
RoundedRectangle(cornerRadius: 20)
.stroke(Color.red, lineWidth: 2)
)

}
else {
NavigationLink(destination: ContentView(), label: {Text("Done")})
.foregroundColor(Color.green)
.background(
RoundedRectangle(cornerRadius: 20)
.stroke(Color.green, lineWidth: 2)
)
}
}         .navigationBarHidden(true)
}

您的timer何时知道何时停止
您必须定义计时器何时停止的事件。这就是.invalidate派上用场的地方。

基本示例:

Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] (timer) in
guard let _weakSelf = self else { timer.invalidate(); return }
_weakSelf.timerVal -= 1
if _weakSelf.timerVal < 0 { //if timer count goes negative then stop timer
timer.invalidate()
} else if _weakSelf.timerVal < 6 {
WKInterfaceDevice.current().play(.success)
}
}

为了获得更多控制,例如,如果您想通过点击按钮来停止timer,那么我们必须将此timer对象设置为全局对象
此外,如果您想在timer完成/取消后弹出View,那么我们需要进行更多更改
这一切变得有点复杂,但理解起来很简单
我建议您将与计时器相关的逻辑分解为ObservableObject类,并在View中使用它。

示例:

struct ContentView: View {
@State var isShowingTimer: Bool = false
var body: some View {
NavigationView {
NavigationLink(destination: TimerView(isShowing: $isShowingTimer),
isActive: $isShowingTimer) {
Text("Start Timer")
}
}
}
}
  • isShowingTimer控制TimerView的推送/弹出事件
    • 它作为绑定发送到TimerView,因此可以从TimerView内部更新以弹出

struct TimerView: View {
//Trigger for popping this view
@Binding var isShowing: Bool
@ObservedObject var timerControl = TimerControl()
var body: some View {
VStack {
Text("(timerControl.count)")
.onAppear(perform: {
//start timer event
self.timerControl.startTimer(from: 10)
})
.onDisappear(perform: {
//stop timer if user taps on `Back` from the Navigation Bar
self.timerControl.stopTimer()
})
.onReceive(timerControl.$isComplete, //observe timer completion trigger
perform: { (success) in
//hide this view
self.isShowing = !success
})
Text("Cancel")
.onTapGesture(perform: {
//stop timer event
self.timerControl.stopTimer()
})
}
}
}

class TimerControl: ObservableObject {
@Published var count: Int = 0
@Published var isComplete: Bool = false
private var timer: Timer?
init(){}
func startTimer(from count: Int) {
self.count = count
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] (timer) in
guard let _weakSelf = self else { timer.invalidate(); return }
print(_weakSelf.count)
_weakSelf.count -= 1
if _weakSelf.count <= 0 {
_weakSelf.stopTimer()
} else if _weakSelf.count < 6 {
print(">>make some noise here<<")
}
}
}
func stopTimer() {
guard isComplete == false else { return }
timer?.invalidate()
isComplete = true
}
}

  • ObservableObject类可以发出更改
  • @Published变量发出变化信号
  • @ObservedObject侦听ObservableObject上的更改
  • .onReceive处理Publisher事件。在这种情况下,侦听timerControl.$isComplete的更改

最新更新