.buttonRepeatBehavior(.enabled)
なるもの、iOS17から使用可能らしい。
* ちなみにこの記事がめでたく300記事目となりました、やったね 🎉
実装
import SwiftUI
struct HomeView: View {
@State private var count = 0
var body: some View {
VStack {
Text("カウント: \(count)")
.font(.largeTitle)
Button {
count += 1
} label: {
Text("Increment")
}
.buttonRepeatBehavior(.enabled)
}
}
}
ロングタップでcount += 1
が繰り返しトリガーされるようになります。
おまけ
何かに使えないかと思って、最近友人のパチンコ話を聞いて平均どれくらいであたるのかのシミュレーションに使ってみた。
1/319の確率で当たる機器が今の最高分母らしいのでそれで試してみる、ガンダムユニコーンくんの機種があるそうなのでそちらで想定 🦄
実装
AudioPlayer.swift
音声再生用、mp3形式で好きなものを入れてください
import UIKit
import AVFoundation
final class AudioPlayer {
var player: AVAudioPlayer?
func playSound() {
guard let url = Bundle.main.url(forResource: "unicorn", withExtension: "mp3") else {
print("Audio file not found")
return
}
do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch {
print("Error playing audio: \(error.localizedDescription)")
}
}
}
HomeView.swift
ボタン押されるたびに1/319の抽選をして、当たりなら音声を再生する。
ここで.buttonRepeatBehavior(.enabled)
が使えそうだったので使ってみる。(まあfor文で回してもいい気がしたが)
そしてListに何回目で当たったのか記録していく。
import SwiftUI
import AVFoundation
struct HomeView: View {
@State private var tryCount: Int = 0
@State private var isButtonDisabled = false
@State private var jackpotHistory: [Int] = []
private let audioPlayer = AudioPlayer()
var body: some View {
VStack(spacing: 24) {
Text("\(tryCount)/319\(isButtonDisabled ? "🦄" : "")")
.font(.largeTitle)
.padding()
List {
ForEach(jackpotHistory, id: \.self) { jackpot in
Text("\(jackpot)/319")
}
}
Button {
tryUnicorn()
} label: {
Text("UNICORN!!!")
}
.frame(width: UIScreen.main.bounds.width / 1.3, height: UIScreen.main.bounds.height / 28, alignment: .center)
.padding()
.foregroundColor(.white)
.background(isButtonDisabled ? .red : .blue)
.clipShape(RoundedRectangle(cornerRadius: 27))
.padding()
.disabled(isButtonDisabled)
.buttonRepeatBehavior(.enabled)
}
}
private func tryUnicorn() {
tryCount += 1
let jackPotNumber = Int.random(in: 1...319)
if jackPotNumber == 13 {
isButtonDisabled = true
audioPlayer.playSound()
jackpotHistory.append(tryCount)
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
tryCount = 0
isButtonDisabled = false
}
}
}
}
10回やってみた結果。
分母内で当たる確率は約60%だそうなので試行回数は少ないですがその辺りに落ち着いてそうですね。