🎣
UITapGestureRecognizer を使うと他のUIViewが反応しない!cancelsTouchesInView の挙動
環境
Ventura 13.6.4
Xcode 15.2
シミュレータ iOS17.2
構造
A: UIView
AG: Aに付けた UITapGestureRecognizer
B: Aに乗っている UIButton
C: Aに乗っている UICollectionView
挙動 cancelsTouchesInView = true (デフォルト)
ボタンを押したとき
- AGは無反応
- ボタンは反応
セルを押したとき
- AGは反応
- コレクションビューは無反応
挙動 cancelsTouchesInView = false
ボタンを押したとき
- AGは反応
- ボタンは反応
セルを押したとき
- AGは反応
- コレクションビューは反応
ソース
import UIKit
class ViewController: UIViewController, UICollectionViewDelegate {
var dataSource: UICollectionViewDiffableDataSource<String, String>! = nil
var collectionView: UICollectionView! = nil
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
configureHierarchy()
configureDataSource()
let b = UIButton(type: .system)
b.setTitle("ボタン", for: .normal)
b.addAction(UIAction(handler: { _ in
print("ボタンが押された")
}), for: .touchUpInside)
b.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
collectionView.frame = CGRect(x: 100, y: 200, width: 100, height: 100)
view.addSubview(b)
view.addSubview(collectionView)
let g = UITapGestureRecognizer(target: self, action: #selector(gPushed))
g.cancelsTouchesInView = false
view.addGestureRecognizer(g)
}
@objc func gPushed() {
print("ジェスチャー")
}
func configureHierarchy() {
collectionView = UICollectionView(
frame: view.bounds,
collectionViewLayout: createLayout())
view.addSubview(collectionView)
collectionView.delegate = self //タップ操作へ対応するため
}
func createLayout() -> UICollectionViewLayout {
let config = UICollectionLayoutListConfiguration(appearance: .grouped)
return UICollectionViewCompositionalLayout.list(using: config)
}
func configureDataSource() {
//【C】リサイクル機能
let cellRegistration = UICollectionView.CellRegistration<UICollectionViewListCell, String> {
(cell, indexPath, identifier) in
var content = cell.defaultContentConfiguration()
content.text = identifier
cell.contentConfiguration = content
}
//データソースの作成
dataSource = UICollectionViewDiffableDataSource<String, String> (collectionView: collectionView) {
//【B】セルの内容が決定
(collectionView: UICollectionView, indexPath: IndexPath, identifier: String) -> UICollectionViewCell? in
return collectionView.dequeueConfiguredReusableCell(
using: cellRegistration,
for: indexPath,
item: identifier)
}
//【A】構成を決める
var snapshot = NSDiffableDataSourceSnapshot<String, String>()
snapshot.appendSections(["one"])
snapshot.appendItems(["one"], toSection: "one")
dataSource.apply(snapshot, animatingDifferences: false)
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("Cell")
}
}
反応しない、UIButton、UICollectionView、UITableView
Discussion