前提
SwiftUIでストップウォッチアプリを作成しようとしています。
計測開始ボタンを押してからの経過秒数を画面に表示しています。
経過秒数が30秒たったところでバイブレーションを作動させたいと思っているのですが、コードの書き方が分からず困っています。
実現したいこと
ここに実現したいことを箇条書きで書いてください。
- 30秒経過時にバイブレーションを作動させる
発生している問題・エラーメッセージ
30秒経過時のバイブレーションをどのようにコードに落とし込めば良いか分かりません。 現状のコードでストップウォッチの機能は完成しています。 また、バイブレーションが作動するかの一時的な確認として、ボタンを押したらバイブレーション作動させるというコードは書けました。 あとはボタンを押さずとも、30秒経過したら自動でバイブレーションにしたいと思っています。
該当のソースコード
SwiftUI
1import SwiftUI 2import AudioToolbox 3 4struct ContentView: View { 5 6 @ObservedObject var managerClass: ManagerClass = ManagerClass() 7 8 //触覚バイブレーション 9 let UINFG = UINotificationFeedbackGenerator() 10 11 var body: some View { 12 ZStack { 13 //背景色 14 Color.black 15 .ignoresSafeArea() 16 17 VStack(spacing: 100) { 18 HStack { 19 Button(action: { 20 AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) {} 21 }) { 22 Text("バイブレーションテスト") 23 } 24 } 25 //時間表示の部分 26 ZStack { 27 managerClass.secondsElapsed < 45.0 ? 28 Text(String(format: "%02d", Int(managerClass.secondsElapsed))) 29 .font(Font(UIFont.monospacedDigitSystemFont(ofSize: 100, weight: .light))) 30 .foregroundColor(.white) 31 : 32 Text("finish") 33 .font(.largeTitle) 34 .foregroundColor(.white) 35 36 //タイマー背景 37 Circle() 38 .trim(from: 0.0, to: 1.0) 39 .stroke(Color.gray, style: StrokeStyle(lineWidth: 10, lineCap: .round)) 40 .frame(width: timerDiameter, height: timerDiameter) 41 .rotationEffect(.init(degrees: -90)) 42 43 //タイマー前面 44 managerClass.secondsElapsed < 45 ? 45 Circle() 46 .trim(from: 0.0, to: managerClass.secondsElapsed / 60.0) 47 .stroke(Color.yellow, style: StrokeStyle(lineWidth: 10, lineCap: .round)) 48 .frame(width: timerDiameter, height: timerDiameter) 49 .rotationEffect(.init(degrees: -90)) 50 : 51 Circle() 52 .trim(from: 0.0, to: 0.75) 53 .stroke(Color.red, style: StrokeStyle(lineWidth: 10, lineCap: .round)) 54 .frame(width: timerDiameter, height: timerDiameter) 55 .rotationEffect(.init(degrees: -90)) 56 } 57 58 //ボタンの部分 59 if managerClass.isTimerRunning { 60 withAnimation { 61 HStack { 62 Spacer() 63 Button(action: { 64 managerClass.reset() 65 self.UINFG.notificationOccurred(.success) 66 }) { 67 Image(systemName: "arrow.left.to.line.circle.fill") 68 .font(.system(size: buttonSize)) 69 .foregroundColor(.white) 70 } 71 Spacer() 72 Button(action: { 73 managerClass.stop() 74 self.UINFG.notificationOccurred(.success) 75 }) { 76 Image(systemName: "pause.circle.fill") 77 .font(.system(size: buttonSize)) 78 .foregroundColor(.white) 79 80 } 81 Spacer() 82 } 83 } 84 } else { 85 withAnimation { 86 HStack { 87 Spacer() 88 Button(action: { 89 managerClass.reset() 90 self.UINFG.notificationOccurred(.success) 91 }) { 92 Image(systemName: "arrow.left.to.line.circle.fill") 93 .font(.system(size: buttonSize)) 94 .foregroundColor(.white) 95 } 96 Spacer() 97 Button(action: { 98 managerClass.start() 99 self.UINFG.notificationOccurred(.success) 100 }) { 101 Image(systemName: "play.circle.fill") 102 .font(.system(size: buttonSize)) 103 .foregroundColor(.white) 104 } 105 Spacer() 106 } 107 } 108 } 109 } 110 } 111 } 112} 113 114class ManagerClass: ObservableObject { 115 //経過時間 116 @Published var secondsElapsed: Double = 0.0 117 //タイマーが動いてる状態がtrue、止まっている状態がfalse 118 @Published var isTimerRunning: Bool = false 119 120 var timer = Timer() 121 122 func start() { 123 isTimerRunning = true 124 timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true){ timer in 125 self.secondsElapsed += 0.01 126 } 127 } 128 func stop() { 129 isTimerRunning = false 130 timer.invalidate() 131 } 132 func reset() { 133 secondsElapsed = 0.0 134 } 135 136} 137 138//画面の幅 139let screenWidth: CGFloat = UIScreen.main.bounds.width 140 141//タイマーの直径 142let timerDiameter: CGFloat = screenWidth * 0.8 143 144//ボタンのサイズ 145let buttonSize: Double = 80.0 146 147struct ContentView_Previews: PreviewProvider { 148 static var previews: some View { 149 ContentView() 150 } 151} 152
試したこと
func start()を以下のように書いて試しましたが、バイブレーションは作動しませんでした。
func start() {
isTimerRunning = true
timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true){ timer in
self.secondsElapsed += 0.01
}
if self.secondsElapsed == 30 {
AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) {}
}
}
補足情報(FW/ツールのバージョンなど)
MacBookのXCodeでコーディングしています。
バイブレーションの作動確認は実機のiPhoneXSをつないで行っています。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/08/16 09:31