I'm trying to add UILongPressGesture to the cell. It is working but only when I long press and move in any direction.
It should call the selector method on long press but it is calling when I long press and started to move. I'm also handling the state of the gesture but selector is not calling until I long press and start moving.
I have also tried with adding gesture to cell's content view and its UIlable element, but no luck.
let longPressGesture: UILongPressGestureRecognizer = {
let gesture = UILongPressGestureRecognizer()
gesture.addTarget(self, action: #selector(MyViewController.handleLongPressGetureForRow(_:)))
gesture.delaysTouchesBegan = false
gesture.cancelsTouchesInView = false
gesture.numberOfTouchesRequired = 1
gesture.minimumPressDuration = 0.2
return gesture
}()
cell.addGestureRecognizer(longPressGesture)
cell.tag = indexPath.row
Cells where adding gesture
Please help me. Thanks in advance.
Instead of handleLongPressGetureForRow(_:) change to self.handleLongPressGetureForRow(v:) with #objc before func
let longPressGesture: UILongPressGestureRecognizer = {
let gesture = UILongPressGestureRecognizer()
gesture.addTarget(self, action: #selector(self.handleLongPressGetureForRow(v:)))
gesture.delaysTouchesBegan = false
gesture.cancelsTouchesInView = false
gesture.numberOfTouchesRequired = 1
gesture.minimumPressDuration = 0.2
return gesture
}()
cell.addGestureRecognizer(longPressGesture)
cell.tag = indexPath.row
return cell
}
#objc func handleLongPressGetureForRow(v: UILongPressGestureRecognizer )
{
print("saghsaghghsgfsgsaghghsaghsaghghsaghashgsasa")
}
Related
I am trying to add tap gesture for a dynamically created UILabel in a function in swift 4, but it is not firing UITapGestureRecognizer function. it is working when i add tap gesture from viewDidLoad function, but i have to add tap gesture from other function.
here is the code
override func viewDidLoad() {
super.viewDidLoad()
createLabel()
}
func createLabel() {
let label = UILabel()
label.text = "abc"
label.numberOfLines = 0
label.frame.size.width = self.otherlinksStack.bounds.width
label.font = label.font.withSize(17) // my UIFont extension
label.sizeToFit()
label.tag = 1
self.otherlinksStack.addSubview(label)
let labelTapGesture = UITapGestureRecognizer(target:self,action:#selector(self.doSomethingOnTap))
label.isUserInteractionEnabled = true
label.addGestureRecognizer(labelTapGesture)
}
#objc func doSomethingOnTap() {
print("tapped")
}
You're doing a couple things wrong...
// your code
label.frame.size.width = self.otherlinksStack.bounds.width
label.sizeToFit()
If you're adding the label to a stackView, there is no need to set its frame -- let the stack view handle that. If your stackView's alignment is set to .fill it will stretch the label to its width anyway. If it's not set to fill, the label will expand horizontally as needed, based on its text. So, also, no need to call .sizeToFit().
// your code
self.otherlinksStack.addSubview(label)
When add a view to a stack view, use .addArrangedSubview, otherwise it will be added overlaid on top of another view in the stack view.
This should work fine (it does in my quick test):
func createLabel() {
let label = UILabel()
label.text = "abc"
label.numberOfLines = 0
label.font = label.font.withSize(17) // my UIFont extension
label.tag = 1
// give the label a background color so we can see it
label.backgroundColor = .cyan
// enable user interaction on the label
label.isUserInteractionEnabled = true
// add the label as an Arranged Subview to the stack view
self.otherlinksStack.addArrangedSubview(label)
// create the gesture recognizer
let labelTapGesture = UITapGestureRecognizer(target:self,action:#selector(self.doSomethingOnTap))
// add it to the label
label.addGestureRecognizer(labelTapGesture)
}
#objc func doSomethingOnTap() {
print("tapped")
}
Use this code for adding the Tap Gesture:
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapGestureMethod(_:)))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
yourLabel.isUserInteractionEnabled = true
yourLabel.addGestureRecognizer(tapGesture)
This is the tap gesture method:
#objc func tapGestureMethod(_ gesture: UITapGestureRecognizer) {
Do your code here
}
func addTapGesture() {
let labelTapGesture = UITapGestureRecognizer(target: self, action: #selector(doSomethingOnTap))
//Add this line to enable user interaction on your label
myLabel.isUserInteractionEnabled = true
myLabel.addGestureRecognizer(labelTapGesture)
}
#objc func doSomethingOnTap() {
print("tapped")
}
Then call addTapGesture() from viewDidLoad or from whichever function you wanna add tap from.
If your gesture works from viewDidLoad, then after adding from other function the gesture might override by other control's gestures..
Try adding gesture on control which is seperate from all other controls.
the UIView in question is headerView:
if isShown {
stack.alpha = 1.0
self.isStackShown = true
DispatchQueue.main.async {
self.headerView.isHidden = !isShown
self.stack.addArrangedSubview(self.headerView)
// add touch gesture recognizer to stack view header
let tapFind = UIGestureRecognizer(target: self, action: #selector(self.handleFindTap))
self.headerView.addGestureRecognizer(tapFind)
}
} else {
stack.alpha = 0.0
self.isStackShown = false
DispatchQueue.main.async {
self.headerView.isHidden = isShown
self.stack.removeArrangedSubview(self.headerView)
}
}
The tap gesture recognizer is not registering any taps
self.stack is the stack view which contains the headerView
The condition for either showing or hiding the headerView is being handled in a different method and just passes the boolean self.isStackShown to this method to show/hide accordingly.
You are using a UIGestureRecognizer. UIGestureRecognizer is a polymorphic base class and should really be subclassed. UITapGestureRecognizer is the concrete subclass for handling taps. Use it instead.
let tapFind = UITapGestureRecognizer(target: self, action: #selector(self.handleFindTap))
self.headerView.addGestureRecognizer(tapFind)
Your action is never getting called because UIGestureRecognizer has no inherent information about what kind of gesture to recognize. Only a concrete subclass of it does.
Looks like you are adding multiple gesture recognizers when changing back the alpha to 1.0 and they aren't able to recognize simultaneously. Remove all gesture recognizers when hiding and removing the headerView since you don't need one anymore and add one back when adding back the headerView and it should work. Or you can also let the gesture recognizer be when hiding the headerView since it won't work anyway and check if one exists before adding another.
if isShown {
stack.alpha = 1.0
self.isStackShown = true
DispatchQueue.main.async {
self.headerView.isHidden = !isShown
self.stack.addArrangedSubview(self.headerView)
// add touch gesture recognizer to stack view header
let tapFind = UIGestureRecognizer(target: self, action: #selector(self.handleFindTap))
self.headerView.addGestureRecognizer(tapFind)
}
} else {
stack.alpha = 0.0
self.isStackShown = false
DispatchQueue.main.async {
self.headerView.isHidden = isShown
self.headerView.gestureRecognizers?.forEach({self.headerView.removeGestureRecognizer($0)})
self.stack.removeArrangedSubview(self.headerView)
}
}
or
if isShown {
stack.alpha = 1.0
self.isStackShown = true
DispatchQueue.main.async {
self.headerView.isHidden = !isShown
self.stack.addArrangedSubview(self.headerView)
if self.headerView.gestureRecognizers?.isEmpty != false{
// add touch gesture recognizer to stack view header
let tapFind = UIGestureRecognizer(target: self, action: #selector(self.handleFindTap))
self.headerView.addGestureRecognizer(tapFind)
}
}
} else {
stack.alpha = 0.0
self.isStackShown = false
DispatchQueue.main.async {
self.headerView.isHidden = isShown
self.stack.removeArrangedSubview(self.headerView)
}
}
I have a UICollectionViewcell in my code
let cell = commentSection.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CommentCell
And in CommentCell i have got this imageview
let likeIcon: UIImageView = {
let imv = UIImageView()
imv.image = #imageLiteral(resourceName: "like")
imv.translatesAutoresizingMaskIntoConstraints = false
return imv
}()
I tried adding a tap gesture to likeIcon in CommentCell and also in cellForItemAt but none of them triggered it when clicking.How can i add gestureTapRecognizer to child element of cell?
Adding UIImageView and providing gesture recognizer will increase the complexity of your development.
If you need action then use UIButton and set target action for button in cellForRowAtIndex
You can set either background image or image to UIButton.
Better keep processed image in UIImage object and assign it to UIButton.
Look at the code:
....
let imageView = UIImageView()
imageView.isUserInteractionEnabled = true
let recognizer = UITapGestureRecognizer()
recognizer.addTarget(self, action: #selector(yourHandleMethod(tapGestureRecognizer:)))
imageView.addGestureRecognizer(recognizer)
....
func yourHandleMethod(tapGestureRecognizer: UITapGestureRecognizer) {
print("tap")
}
Call this method update() outside in cellForItem (for every cell).
...
cell.update()
...
// This method inside cell
func update() {
let recognizer = UITapGestureRecognizer()
recognizer.addTarget(self, action: #selector(yourHandleMethod(tapGestureRecognizer:)))
imageView.addGestureRecognizer(recognizer)
}
I added an UITapGestureRecogniser to my tableViewCell which recognizes if the user double tapped a cell. If I double tap the cell, the function didSelectRowAtIndexPath gets automatically called. I just want that the func of the gesturerecogniser gets called if the user do a double tap on a cell and not both. Does someone have an idea to solve this?
In viewDidLoad function :
let aSelector : Selector = “start:”
let tapGesture = UITapGestureRecognizer(target: self, action: aSelector)
tapGesture.numberOfTapsRequired = 1
view.addGestureRecognizer(tapGesture)
let bSelector : Selector = “stop:”
let doubleTapGesture = UITapGestureRecognizer(target: self, action: bSelector)
doubleTapGesture.numberOfTapsRequired = 2
view.addGestureRecognizer(doubleTapGesture)
tapGesture.requireGestureRecognizerToFail(doubleTapGesture)
The action aSelector will be called on single tap and bSelector on double tap.
I am trying to fire event with UITapGestureRecognizer on different uiview but it is not working.
var tap = UITapGestureRecognizer(target: self, action: Selector("tappedMe"))
AUIView.addGestureRecognizer(tap)
AUIView.tag = 1
BUIView.addGestureRecognizer(tap)
BUIView.tag = 2
func tappedMe()
{
if AUIView.tag == 1
{
println("1")
}
else if BUIView.tag == 2
{
println("2")
}
}
You cannot add the same gesture recognizer to multiple views. This answer explains why.
Either declare a new gesture recognizer, or create a copy of the existing one before adding it to the other view.
BUIView.addGestureRecognizer(tap.copy())