问题
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