UITableView need long press to select a row - ios

Anyone has ever come into the problem that UITableView need long press to trigger the didSelectRowAtIndexPath method?

If you have used any gesture recognizer try to removing it and check if it causing the problem or not ?
Other wise
Not sure but The problem might be in the UITableView has delaysContentTouches turned ON. Turn this OFF so touches get through to the cells faster.

In my situation I had a UITapGestureRecognizer on my view for hiding my keyboard.
This solved the problem:
tap.cancelsTouchesInView = false

I had exactly the same trouble :
I used the Tap Gesture recognizer to manage different action in my View Controller
I wanted a classic tap (short click) to trigger the didSelectRowAtIndexPath method but just a long press working by default
My solution to select a cell in Table View by a short tap (press) :
Select your Tap Gesture recognizer in your Story Board
Go to the attributes inspector and deselect "Canceled in view"

You have to add UILongPressGesture to your cell's view and on fire just call didSelectRowAtIndexPath (better will be to call another method - not standard UITableViewDelegate's method) from your class that adopts UITableViewDelegate.
I will suggest You create own protocol, inherited from UITableViewDelegate, add there method for long press behavior method and enjoy. Something similar to:
#protocol LongPressTableViewCellDelegate <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didLongTapCell:(UITableViewCell *)cell;
#end
Your delegate in this case would adopt not standard UITableViewDelegate, but this one. Also You have to create own cell (inherited from UITableViewCell) and add there delegate property (id ) that will be used when long press fired.
Also there can be situation that standard didSelectRowAtIndexPath will be fired before your long press will fire, so I suggest you to disable standard selection behavior for table view:
_tableView.allowsSelection = NO;

Related

tableView:canEditRowAtIndexPath difficult to receive event

I have a customised cell that need to receive the swipe event so it can show the delete button on the right side.
It is an iPad application.
The problem is that it is very difficult to receive the event. Just when swiping very fast that the delegate is called. In other cells in my project this is not happening.
I tried to remove the views inside the cell and it is still difficult.
Also tried to just return yes on the canEditRowAtIndexPath delegate instead of all my logic inside. But the problem is that the delegate is not called.
I also checked if there is any gesture recogniser that is confusing the default swipe recog.
Anyone has a tip?
I had the same problem using SWRevealViewController, so I canceled the swipe touch using this delegate
- (BOOL)revealControllerPanGestureShouldBegin:(SWRevealViewController *)revealController
{
return NO;
}

UICollectionView didSelectItemAtIndexPath not called when tapped on UITextView

I have a UICollectionView with custom cells- They have a UITextView that mostly covers the entire cell. This presents a problem when using didSelectItemAtIndexPath. The only way to trigger it is by tapping outside the UITextView. I want it to trigger wherever in the cell you tap, whether there is a text view or not. How can this be done?
didSelectItemAtIndexPath is called when none of the subView of collectionViewCell respond to that touch. As the textView respond to those touches, so it won't forward those touches to its superView, so collectionView won't get it.
override hitTest:withEvent method of your collectionViewCell or CollectionView subclass and always return self from them.so it explicitly makes collectionView as first responder.
I would suggest to use UIGestureRecognizer for each cell and when it taped to send it to UITextView or whatever , perhaps there maybe a better solutions , but I would use this 1 because of simplicity reasons.
Do you override touchesEnded: withEvent: ?
I had the same problem today and I found that I have some customised logic in touchesEnded in one of collectionview's container views, and I didn't call
[super touchesEnded: withEvent:]
when I'm done with my customised logic in touchesEnded.
After adding the super call, everything is fine.
Select UITextView, in that specific case UICollectionViewCell, and switch to attribute inspector. The uncheck User interaction enabled and it should work fine.
I ran into this problem when I had a scroll view taking up my entire collection view cell. While all the solutions above probably work fine, I came up with my own elegant work-around. I put a 'select' label under my scroll view. Since the label is not part of the scroll view, it passes the tap event on to the collection view. It also serves as a nice indicator that an action is required of the user.
Just do this
textview.isUserInteractionEnabled = false

Custom UITableViewCell, button in cell not working

I have a UITableViewController where I'm working with a custom UITableViewCell. The cell contains an image, labels and buttons. Everything is working as expected except of the buttons. When pressing the button, nothing happens. Only the cell gets selected.
I made a connection in IB from the button to my custom TweetTableViewCell class.
#property (weak, nonatomic) IBOutlet UIButton *cellFollowButton;
- (IBAction)followButtonTappedonCell:(id)sender;
I'm writing some text to the console in my followButtonTappedonCell action. But when pressing the button, nothing happens. It seems to me that some view consumes the tap before it arrives to the button. To make it more confusing... When I add a button in may UITableViewController programatically like this:
[cell.cellFollowButton addTarget:self action:#selector(customActionPressed) forControlEvents:UIControlEventTouchDown];
[cell addSubview:cell.cellFollowButton];
...it just works.
I read in other articles that disabling "User Interaction Enabled" solved similar problems, but it doesn't in my case.
I'm sure that many others must have run into this problem when using buttons in UITableViewCells. Any help is highly appreciated.
I'm using Xcode 5 for iOS 7.
If your cell is in a nib, make sure the root object is a UITableViewCell and NOT a UIView
I would recommend you to go through this link. It has clear description of your problem. However, I've tried to extract needed info.
Many types of events rely on a responder chain for event delivery. The responder chain is a series of linked responder objects. It starts with the first responder and ends with the application object. If the first responder cannot handle an event, it forwards the event to the next responder in the responder chain.
A responder object is an object that can respond to and handle events. The UIResponder class is the base class for all responder objects, and it defines the programmatic interface not only for event handling but also for common responder behavior. Instances of the UIApplication, UIViewController, and UIView classes are responders, which means that all views and most key controller objects are responders.
In your Case, when you are writing event methods in your customTableViewCell class, your methods are not being called. this is because, TableViewCell is not participating in Responder chain.
next thing is, check whether "User Interaction is enabled " or not for your Cell. You can find it under View section of "Attribute inspector".

Animation while delete or reorder the cell in table view

I would like to implement an animation when a user tries to delete and reorder a cell. Now it is coming instantly when I click on the edit button. Can you help me to make this code as an iphone contact app animation.
-(IBAction)edit:(id)sender
{
tabView.editing = !tabView.editing;
}
Take a look at UITableView class reference and you should be able to find the instance method you need.
The instance method setEditing:animated: will be able to do what you want. The second parameter will give the animation transition if you set it to YES.
For example:
[tabView setEditing:!tabView.editing animated:YES];

UICollectionView only calling didSelectItemAtIndexPath if user double taps, will not call when user single taps

I have a UICollectionView which is about the size of the screen. The UICollectionViewCells that it displays are the same size as the collectionView. Each cell has a UIImage which is the size of the cell. The CollectionView has paging enabled so essentially it is a full screen photo slideshow that the user can swipe through.
The problem is that
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath is only being called if the user taps with two fingers on a cell or long presses with one finger and then releases. It does not seem to have the default behaviour of single tap selection. I have not made any changes to the CollectionView gesture recognizer so am having trouble finding a solution to this problem.
Are you sure you're not accidentally overriding - (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath? "Select" vs. "deselect" has tripped me up in the past with Xcode's code completion.
I was just having the same problem and it turned out that there was a UITapGestureRecognizer on the UIView containing the UICollectionView and it was responding instead.
That explains why didSelectItemAtIndexPath works only if the user taps with two fingers or long presses with one finger because that doesn't trigger the UITapGestureRecognizer.
So, check all the UITapGestureRecognizer you got there, not necessarily on the UICollectionView directly but it could be on any UIView containing it.
If you have a view on the cell which obstructs the cells content view that is intractable then you will not be able to hook into the delegate callback for the cell.
You will want to disable user interaction on the obstructing view either in the NIB or in the code.
view.userInteractionEnabled = NO;
Just add to the already resolved question one more situation where the tap gesture might not work, since this did keep tormenting me.
If you return false within UICollectionViewDelegate's collectionView:shouldHighlightItemAtIndexPath:, the tap gesture won't function and the collectionView:didSelectItemAtIndexPath: would not be called. The default return value of this delegate method is true, so you won't have the problem if you don't implement it deliberately.
I just ran into this problem myself. Originally I had buttons and labels, then I refactored my UI and turned those button/labels into cells for a UICollectionView.
I eventually realized the buttons were consuming my taps. I had unthinkingly just moved my original buttons into the cell, and not turned it into a straight UIImage. I had destroyed the actions associated buttons and was just looking for cell selection so I took me a while to figure it out.
Stupid and obvious in retrospect, but took me a couple hours to realize what I had done.
If you use only didselect:
self.collectionView.allowsMultipleSelection = false
Or delete that line.
I just had the same problem...I was overriding touchesBegan in the CollectionCell view and this caused the didSelectItemAtIndexPath to not fire when I touched the cell. Removed the override and all worked.
In my case it was just
self.collectionView.allowsSelection =NO;
I had in code.
changing to
self.collectionView.allowsSelection =YES;
fix it.
Try removing all of your UIGestures from the view then test to see if the UICollectionView Cells are able to be interacted with normally.
In my case, I had to remove the lines:
let tap = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
self.view.addGestureRecognizer(tap)
I ran into this problem in Swift 3 and xcode 8 , I had a view and a collection view inside this.The collection view has userInteractionEnabled to true , still it was not working.Fixed this issue by overriding shouldHighlightItemAt , I dont have any extra / custom implementation in this method , so i did not override this method.After adding the below code the didSelectItem method is called.
func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
return true
}
I'm happened to stumble upon this problem, and it frustrated me one long day until I found this You just need to uncheck "User Interaction Enabled"
when I selected the Cell on the top left inside the CollectionView in Storyboard. and problem solved
I faced a similar problem and the culprit in my case turned out to be the CardView I was using in UICollectionView Cell's heirarchy. As soon as I disabled the user interaction for the CardView the collectionView started responding to the touch events.
In case it helps, this just bite me in a silly way spending a couple of hours. Double check if your custom cell is subclassing UICollectionViewCell instead of, let's say, UICollectionReusableView 😂
the top answer works in many cases. but for me, I have a page with complicated gesture, and I met the same situation and the answer does not work for me, finally I got my way:
when adding gestures, set delegate and use this protocal method to deal with it
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
in this method, you can decide whether the gesture recognizer to receive the touch by your own logic, no matter position or the page's hidden property, based on your demand.
once the method return NO, the gesture won't react the touch, in this case the collectionView or tableView can react the selection correctly.
Remember to add UICollectionViewDataSource, UICollectionViewDelegate to the class

Resources