質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

解決済

【SwiftUI】一定時間経過後にバイブレーションを作動させる方法

Koya
koya

総合スコア1

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

1回答

0リアクション

0クリップ

195閲覧

投稿2022/08/15 08:17

前提

SwiftUIでストップウォッチアプリを作成しようとしています。
計測開始ボタンを押してからの経過秒数を画面に表示しています。
経過秒数が30秒たったところでバイブレーションを作動させたいと思っているのですが、コードの書き方が分からず困っています。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • 30秒経過時にバイブレーションを作動させる

発生している問題・エラーメッセージ

30秒経過時のバイブレーションをどのようにコードに落とし込めば良いか分かりません。 現状のコードでストップウォッチの機能は完成しています。 また、バイブレーションが作動するかの一時的な確認として、ボタンを押したらバイブレーション作動させるというコードは書けました。 あとはボタンを押さずとも、30秒経過したら自動でバイブレーションにしたいと思っています。

該当のソースコード

SwiftUI

import SwiftUI import AudioToolbox struct ContentView: View { @ObservedObject var managerClass: ManagerClass = ManagerClass() //触覚バイブレーション let UINFG = UINotificationFeedbackGenerator() var body: some View { ZStack { //背景色 Color.black .ignoresSafeArea() VStack(spacing: 100) { HStack { Button(action: { AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) {} }) { Text("バイブレーションテスト") } } //時間表示の部分 ZStack { managerClass.secondsElapsed < 45.0 ? Text(String(format: "%02d", Int(managerClass.secondsElapsed))) .font(Font(UIFont.monospacedDigitSystemFont(ofSize: 100, weight: .light))) .foregroundColor(.white) : Text("finish") .font(.largeTitle) .foregroundColor(.white) //タイマー背景 Circle() .trim(from: 0.0, to: 1.0) .stroke(Color.gray, style: StrokeStyle(lineWidth: 10, lineCap: .round)) .frame(width: timerDiameter, height: timerDiameter) .rotationEffect(.init(degrees: -90)) //タイマー前面 managerClass.secondsElapsed < 45 ? Circle() .trim(from: 0.0, to: managerClass.secondsElapsed / 60.0) .stroke(Color.yellow, style: StrokeStyle(lineWidth: 10, lineCap: .round)) .frame(width: timerDiameter, height: timerDiameter) .rotationEffect(.init(degrees: -90)) : Circle() .trim(from: 0.0, to: 0.75) .stroke(Color.red, style: StrokeStyle(lineWidth: 10, lineCap: .round)) .frame(width: timerDiameter, height: timerDiameter) .rotationEffect(.init(degrees: -90)) } //ボタンの部分 if managerClass.isTimerRunning { withAnimation { HStack { Spacer() Button(action: { managerClass.reset() self.UINFG.notificationOccurred(.success) }) { Image(systemName: "arrow.left.to.line.circle.fill") .font(.system(size: buttonSize)) .foregroundColor(.white) } Spacer() Button(action: { managerClass.stop() self.UINFG.notificationOccurred(.success) }) { Image(systemName: "pause.circle.fill") .font(.system(size: buttonSize)) .foregroundColor(.white) } Spacer() } } } else { withAnimation { HStack { Spacer() Button(action: { managerClass.reset() self.UINFG.notificationOccurred(.success) }) { Image(systemName: "arrow.left.to.line.circle.fill") .font(.system(size: buttonSize)) .foregroundColor(.white) } Spacer() Button(action: { managerClass.start() self.UINFG.notificationOccurred(.success) }) { Image(systemName: "play.circle.fill") .font(.system(size: buttonSize)) .foregroundColor(.white) } Spacer() } } } } } } } class ManagerClass: ObservableObject { //経過時間 @Published var secondsElapsed: Double = 0.0 //タイマーが動いてる状態がtrue、止まっている状態がfalse @Published var isTimerRunning: Bool = false var timer = Timer() func start() { isTimerRunning = true timer = Timer.scheduledTimer(withTimeInterval: 0.01, repeats: true){ timer in self.secondsElapsed += 0.01 } } func stop() { isTimerRunning = false timer.invalidate() } func reset() { secondsElapsed = 0.0 } } //画面の幅 let screenWidth: CGFloat = UIScreen.main.bounds.width //タイマーの直径 let timerDiameter: CGFloat = screenWidth * 0.8 //ボタンのサイズ let buttonSize: Double = 80.0 struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }

試したこと

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をつないで行っています。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています