Tap Gesture not working as expected when added to uiview in collectionview cell

左心房为你撑大大i 提交于 2020-01-13 18:55:49

问题


I am adding a tap gesture recognizer programmatically to a custom collection view cell class. for some reason, it doesnt seem to be working. the frame is not 0, isUserInteractionEnabled is set to true and i made sure the tap view is on top of all other views:

The custom cell 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)
}

In the view controller file that has the collection view:

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
}

I do realize that there is a didSelectItemAt method but I am trying some custom behavior that detects multiple taps to a cell and performs an action


回答1:


The problem is that in your definition of tap property, self is not the instance of the custom cell class because at the time the property is created, the object hasn't been fully initialized.

If you add:

print(type(of: self))

to that code, you will see that it prints:

(CustomCell) -> () -> CustomCell

instead of the desired:

CustomCell

So your target/action is using the wrong target.

An easy way to fix this is to make tap a lazy var:

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

Then, the first time you access tap, the tap gesture recognizer will be created and at that time, your custom cell will be created and self will refer to the instance of the class.


Alternatively, you can make tap a computed property:

var tap: UITapGestureRecognizer {
    let t = UITapGestureRecognizer(target: self, action: #selector(tapped))
    return t
}

and tap will create and return a UITapGestureRecognizer when it is accessed. Again, in that case, the custom cell will be created, so self will properly refer to the instance of the class.



来源:https://stackoverflow.com/questions/53716478/tap-gesture-not-working-as-expected-when-added-to-uiview-in-collectionview-cell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!