현재 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
개체를 전역 으로 만들어야합니다 .
또한 완료 / 취소 View
후 팝업을 표시하려면 timer
더 많은 변경이 필요합니다.
이 모든 것이 조금 복잡해 지지만 이해하기 쉽습니다.
타이머 관련 로직을 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
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다