添加到集合视图单元格中的 uiview 时,点击手势无法按预期工作

use*_*097 4 uigesturerecognizer uitapgesturerecognizer uicollectionviewcell swift

我正在以编程方式将点击手势识别器添加到自定义集合视图单元格类中。由于某种原因,它似乎不起作用。框架不为 0,isUserInteractionEnabled 设置为 true,并且我确保点击视图位于所有其他视图之上:

自定义单元格类:

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)
}
Run Code Online (Sandbox Code Playgroud)

在具有集合视图的视图控制器文件中:

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
}
Run Code Online (Sandbox Code Playgroud)

我确实意识到有一个 didSelectItemAt 方法,但我正在尝试一些自定义行为来检测对单元格的多次点击并执行操作

vac*_*ama 5

问题在于,在tap属性的定义中,self不是自定义单元类的实例,因为在创建属性时,对象尚未完全初始化。

如果您添加:

print(type(of: self))
Run Code Online (Sandbox Code Playgroud)

对于该代码,您将看到它打印:

(CustomCell) -> () -> CustomCell
Run Code Online (Sandbox Code Playgroud)

而不是所需的:

CustomCell
Run Code Online (Sandbox Code Playgroud)

所以你的目标/动作使用了错误的目标。

解决这个问题的一个简单方法是制作tap一个lazy var

lazy var tap: UITapGestureRecognizer = {
    let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
    return t
}()
Run Code Online (Sandbox Code Playgroud)

然后,第一次访问时tap,将创建点击手势识别器,此时,将创建您的自定义单元格并将self引用该类的实例。


或者,您可以创建tap一个计算属性

var tap: UITapGestureRecognizer {
    let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
    return t
}
Run Code Online (Sandbox Code Playgroud)

并在访问时tap创建并返回 a 。UITapGestureRecognizer同样,在这种情况下,将创建自定义单元格,因此self将正确引用该类的实例。