UILongTapGuestureRecognizerで対処から位置がズレたらキャンセルする
UIButtonのような挙動をViewで作りたい時にはUILongTapGuestureRecognizerを使うことで実現できます。
ちなみにUITapGuestureRecognizerではボタンのような動きを再現することができません。それについては以前にk時にしたのでそちらを参照してみてくださいUITapGuestureRecognizerではbigin,cancellは取れない
コード
class ViewController: UIViewController {
@IBOutlet weak var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
let longTapGuesture: UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(thumbnailTap(_:)))
longTapGuesture.minimumPressDuration = 0.0
myView.addGestureRecognizer(longTapGuesture)
}
@objc private func thumbnailTap(_ sender: UILongPressGestureRecognizer) {
let touchPos = sender.location(in: sender.view)
switch sender.state {
case .began:
myView.backgroundColor = .systemGreen
case .ended:
myView.backgroundColor = .systemPink
case .changed:
let myViewPos = myView.frame.origin
let normalizePos = CGPoint(x: myViewPos.x + touchPos.x, y: myViewPos.y + touchPos.y)
if !myView.frame.contains(normalizePos) {
myView.backgroundColor = .systemPink
}
default: //キャンセルの処理
myView.backgroundColor = .systemGreen
}
}
}
CGPointがViewの中に含まれるかの判定
UIViewのframeにはcontainsというメソッドが用意されているのでCGPointを渡すことで判定できます。
座標の正規化について
UILongPressGestureRecognizerをViewに対して付与するのでtapした座標はviewの左上を原点とした座標が帰ってきます。
そのためVC上の原点とViewの原点を合わせてあげないと、tapしている位置がviewの上なのかどうかを判定することができません。
let normalizePos = CGPoint(x: myViewPos.x + touchPos.x, y: myViewPos.y + touchPos.y)