在 collectionview 单元格中添加到 uiview 时点击手势无法按预期工作
Tap Gesture not working as expected when added to uiview in collectionview cell
我正在以编程方式将点击手势识别器添加到自定义集合视图单元格 class。出于某种原因,它似乎不起作用。框架不为 0,isUserInteractionEnabled 设置为 true,我确保点击视图位于所有其他视图之上:
自定义单元格class:
let containerView: UIView = {
let view = UIView()
view.isUserInteractionEnabled = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let tapView: UIView = {
let v = UIView()
v.isUserInteractionEnabled = true
return v
}()
let tap: UITapGestureRecognizer = {
let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
return t
}()
@objc fileprivate func tapped() {
print("tap")
}
func setTap() {
self.containerView.addSubview(tapView)
tapView.frame = self.frame
// layout constraint code - printing frame shows its not 0 after this
tapView.addGestureRecognizer(tap)
}
在包含集合视图的视图控制器文件中:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SuggestCell
cell.category.text = data[indexPath.row].category
cell.word.text = data[indexPath.row].word
cell.setTap()
print(cell.tapView.frame)
return cell
}
我知道有一个 didSelectItemAt 方法,但我正在尝试一些自定义行为来检测对单元格的多次点击并执行操作
问题在于,在您定义的 tap
属性 中,self
不是自定义单元格 class 的实例,因为当时 属性被创建,对象还没有完全初始化。
如果您添加:
print(type(of: self))
对于该代码,您将看到它打印:
(CustomCell) -> () -> CustomCell
而不是所需的:
CustomCell
所以你的 target/action 使用了错误的目标。
解决此问题的一个简单方法是将 tap
设为 lazy var
:
lazy var tap: UITapGestureRecognizer = {
let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
return t
}()
然后,当您第一次访问 tap
时,将创建点击手势识别器,届时将创建您的自定义单元格,并且 self
将引用 class.
或者,您可以使 tap
成为 计算的 属性:
var tap: UITapGestureRecognizer {
let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
return t
}
and tap
将在访问时创建 return 和 UITapGestureRecognizer
。同样,在这种情况下,将创建自定义单元格,因此 self
将正确引用 class.
的实例
我正在以编程方式将点击手势识别器添加到自定义集合视图单元格 class。出于某种原因,它似乎不起作用。框架不为 0,isUserInteractionEnabled 设置为 true,我确保点击视图位于所有其他视图之上:
自定义单元格class:
let containerView: UIView = {
let view = UIView()
view.isUserInteractionEnabled = true
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
let tapView: UIView = {
let v = UIView()
v.isUserInteractionEnabled = true
return v
}()
let tap: UITapGestureRecognizer = {
let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
return t
}()
@objc fileprivate func tapped() {
print("tap")
}
func setTap() {
self.containerView.addSubview(tapView)
tapView.frame = self.frame
// layout constraint code - printing frame shows its not 0 after this
tapView.addGestureRecognizer(tap)
}
在包含集合视图的视图控制器文件中:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! SuggestCell
cell.category.text = data[indexPath.row].category
cell.word.text = data[indexPath.row].word
cell.setTap()
print(cell.tapView.frame)
return cell
}
我知道有一个 didSelectItemAt 方法,但我正在尝试一些自定义行为来检测对单元格的多次点击并执行操作
问题在于,在您定义的 tap
属性 中,self
不是自定义单元格 class 的实例,因为当时 属性被创建,对象还没有完全初始化。
如果您添加:
print(type(of: self))
对于该代码,您将看到它打印:
(CustomCell) -> () -> CustomCell
而不是所需的:
CustomCell
所以你的 target/action 使用了错误的目标。
解决此问题的一个简单方法是将 tap
设为 lazy var
:
lazy var tap: UITapGestureRecognizer = {
let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
return t
}()
然后,当您第一次访问 tap
时,将创建点击手势识别器,届时将创建您的自定义单元格,并且 self
将引用 class.
或者,您可以使 tap
成为 计算的 属性:
var tap: UITapGestureRecognizer {
let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
return t
}
and tap
将在访问时创建 return 和 UITapGestureRecognizer
。同样,在这种情况下,将创建自定义单元格,因此 self
将正确引用 class.