UIButtonに3D Touchをつける
peek,popで使われる3DtouchをUIButtonで使えたらいいなと思いカスタムボタンを作成してみました。
趣味で作っているBLEアプリで、デバイスのリモコンを作る際にボタンを押す力でスピードを変えるのに使いました。ゲームなどで使っても面白いかなと思います。
カスタムボタン
指圧が変化した際にtouchesMovedが呼ばれる為touchesMovedでも処理を読んでいます。
また、touchesEndedで0を指定しない場合最後の値が0でない数値が入ってしまう場合があるので0を指定しています
import UIKit
class ForceButton: UIButton {
var force: Float = 0.0
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
pressStrength(touches: touches)
super.touchesBegan(touches, with: event)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
pressStrength(touches: touches)
super.touchesMoved(touches, with: event)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
force = 0.0
super.touchesBegan(touches, with: event)
}
func pressStrength(touches: Set<UITouch>) {
if traitCollection.forceTouchCapability == .available {
for touch:UITouch in touches {
let strength = Float(touch.force / touch.maximumPossibleForce)
force = strength
}
}
}
}
ViewControllerで呼び出し
変化した際値が欲しかったので.allTouchEventsをトリガにしてメソッドを呼び出すようにしています。
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button.addTarget(self, action: #selector(tapped(_:)), for: .allTouchEvents)
}
@objc func tapped(_ sender: ForceButton) {
print(sender.force)
}
}
出力ログはこんな感じです。