This question already has answers here:
UITapGestureRecognizer breaks UITableView didSelectRowAtIndexPath
(21 answers)
Closed 5 years ago.
I have added UITableView on top of UIView. Added tap gesture to UIView using below code:
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapToClose))
tapGesture.cancelsTouchesInView = false
tapGesture.numberOfTapsRequired = 1
vwForTouchClose.addGestureRecognizer(tapGesture)
when I select on cell didSelectRowAt not getting called instead gesture method is called.
Below is ur code at didSelectRowAt:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
Please help me to solve this issue.
You have to cancel UIGestureRecognizer's touches on the TableView. Use delegate method of Gesture Recognizer:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isDescendantOfView:yourTableView]) {
return NO;
}
return YES;
}
Related
In my Swift code, I have a UICollectionViewCell with 3 buttons (all three have IBActions). From my UICollectionViewController I now want to "catch" the individual button taps.
I've followed this StackOverflow question and I can catch the UICollectionViewCell's touch-up inside up in my CollectionViewController with adding this line to the viewDidLoad
gestureRecognizer.cancelsTouchesInView = false
and with this function
func handleTapForCell(recognizer: UITapGestureRecognizer){
//I can break in here
}
But the piece missing now is how can I figure out which of the three buttons have been tapped? I have set different tags on the buttons but I have not found any place on the gestureRecognizer dealing with these tags.
Any ideas?
I think, you don't need to add Gesture on cell to get a button action of a tableviewCell. This code may help you:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
//Your tableviewCell code here
//set tag of cell button
cell.button1.tag = 1
cell.button2.tag = 2
cell.button3.tag = 3
//add action of your cell button
cell.button1.addTarget(self, action: Selector("cellButtonTapped:event:"), forControlEvents: .TouchUpInside)
cell.button2.addTarget(self, action: Selector("cellButtonTapped:event:"), forControlEvents: .TouchUpInside)
cell.button3.addTarget(self, action: Selector("cellButtonTapped:event:"), forControlEvents: .TouchUpInside)
// return cell
}
func cellButtonTapped(sender:UIButton, event:AnyObject){
let touches: NSSet = event.allTouches()!
let touch = touches.anyObject()
let currentTouchPosition: CGPoint = (touch?.locationInView(YOUR_TABLEVIEW_INSTANCE))!
if let indexPath: NSIndexPath = self.YOUR_TABLEVIEW_INSTANCE.indexPathForRowAtPoint(currentTouchPosition)!{
if sender.tag == 1{
//cell first button tap
}else sender.tag == 2{
//cell second button tap
}
else sender.tag == 3{
//cell 3rd button tap
}
}
}
You can follow the protocol/delegate paradigm.
What you need to do is define a protocol in Custom cell. Then make the viewcontroller subscribe to the cell delegate.
Implement the IBActions inside the custom cell class. Call the delegate methods in the IBActions of the buttons. viewcontroller who is delegating for the cell will receive the callbacks for button taps inside the cell.
This question already has answers here:
Swift - add gesture recognizer to object in table cell
(3 answers)
Closed 6 years ago.
So I've been trying to get any row to act like a segue to the next class, kind of like how if you swipe left you can delete the row, after adding the func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath)
but instead in stead of deleting it I would like it to show the another class. If anyone could help it would be great thanks
You can add swiprgesturerecognizer something like,
class MyViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
var recognizer = UISwipeGestureRecognizer(target: self, action: "didSwipe")
self.tableView.addGestureRecognizer(recognizer)
}
func didSwipe(recognizer: UIGestureRecognizer) {
if recognizer.state == UIGestureRecognizerState.Ended {
let swipeLocation = recognizer.locationInView(self.tableView)
if let swipedIndexPath = tableView.indexPathForRowAtPoint(swipeLocation) {
if let swipedCell = self.tableView.cellForRowAtIndexPath(swipedIndexPath) {
// Swipe happened. Do stuff!
}
}
}
}
}
This was an example, manage it as your need. you can add swipegesture's direction property for handle particular direction's swipe like UISwipeGestureRecognizerDirection.Left or Right.
You can refer this answer as a reference.
Hope this will help :)
If I'm understanding the question correctly, you would like so that the user would swipe left on a cell, and it would trigger a segue?
If this is the case, you could try adding a UISwipeGestureRecognizer to the cell using the addGestureRecognizer method, within the cellForRow method of the UITableViewDataSource class.
Hope this helps!
I have a table cell view with 4 UIButtons:
Buttons have Touch Up Inside event
#IBAction func increasDealRatingAction(sender:UIButton) {
let buttonPosition = sender.convertPoint(CGPointZero, toView: self.tableView)
if let indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition) {
...
}
}
And i have edit actions for each cell:
func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
...
return [addToWishListAction, addToPurchasesAction, deleteAction]
}
The issue, when you swipe left to show “add to wish list”, ”delete” actions from position of star buttons, click event handled too or swipe action doesn't detect while you swipe on button area.
Add a swipe gesture recognizer to the buttons
let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("handleSwipes:")) // nil for selector is also possible
swipeGestureRecognizer.direction = .Left // Add this if you want only one direction
dealRatingButton.addGestureRecognizer(swipeGestureRecognizer)
// Add three star buttons
and impletment gestureRecognizer(_:shouldReceiveTouch:) to return false.
I have a ViewController which has textSearchTableView: UITableView and searchBar: UISearchBar
I added UITapGestureRecognizer to dissmis the keyboard
override func viewDidLoad() {
// ...
self.tap = UITapGestureRecognizer(target: self, action: "DissmissKeyboard")
self.tap.delegate = self
self.view.addGestureRecognizer(self.tap)
// ...
}
func DissmissKeyboard()
{
view.endEditing(true)
}
I have added this function to prevent breaking (didSelectRowAtIndexPath) function after selecting the cell
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
if touch.view.isDescendantOfView(self.textSearchTableView) {
return false
}
return true
}
But the problem is: when the keyboard is enabled and i want to dissmiss it,
if i click on the textSearchTableView, (didSelectRowAtIndexPath) will run
How can i dissmiss the keyboard if i click on the tableView without calling (didSelectRowAtIndexPath) ? and I don't want to break this function as well
I hope that I describe the problem well
Thanks a lot
Re-write your didSelectRowAtIndexPath like this:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if (self.searchBar.isFirstResponder())
{
self.searchBar.resignFirstResponder()
}
else
{
//Do something here
}
}
Alternatively: We usually use this approach in tableviews.
self.tableView.keyboardDismissMode = .OnDrag
This will dismiss keyboard when a drag begins in the tableview.
How about you have your tableview's delegate return nil for
- (NSIndexPath *)tableView:(UITableView *)tableView
willSelectRowAtIndexPath:(NSIndexPath *)indexPath
As willSelectRowAtIndexPath is probably what you want but not what you asked for: dismissing the keyboard is done by sending the first responder resignFirstResponder, for sake of answering the actual question.
I'm trying to add a swipe gesture (left/right) in order to hide/show my side menu.
I got it working perfectly on a UIView, however, I'm having trouble with an UITableView.
Here's my code to add my swipe gestures to my TableView:
// Add right swipe gesture recognizer
let rightSwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "toggleSideMenu")
rightSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Right
self.timelineTableView.addGestureRecognizer(rightSwipeGestureRecognizer)
// Add left swipe gesture recognizer
let leftSwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: "toggleSideMenu")
leftSwipeGestureRecognizer.direction = UISwipeGestureRecognizerDirection.Left
//sideMenuContainerView.addGestureRecognizer(rightSwipeGestureRecognizer)
self.timelineTableView.addGestureRecognizer(leftSwipeGestureRecognizer)
Here's my selector method :
func toggleSideMenu() {
println("ENTER SWIPE")
toggleSideMenuView()
}
I've also done this :
func tableView(tableView: UITableView, editingStyleForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCellEditingStyle {
return UITableViewCellEditingStyle.None
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return false
}
However, my selector menu "toggleSideMenu()" is never called when I swipe left or right.
P.S: I've also tried to add those swipe gesture on my UITableViewCell directly but it doesn't work as well.
Anyone has an idea? Thanks a lot for your time!
Thanks to Kirit Modi. Here's the solution to my problem:
Add :
leftSwipeGestureRecognizer.delegate = self
rightSwipeGestureRecognizer.delegate = self
Then add the UIGestureRecognizerDelegate delegate method :
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
return true
}
For me helped
(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
because i had two gestures. One from slide menu and one from current VC. So that one from slide menu killed VC's gestures.