UICollectionView didSelectItemAtIndexPath not called when tapped on UITextView - ios

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

Related

UIButton default tap animation inside UITableViewCell

I have a few UIButtons inside UITableViewCells, and all of them are missing default tap animation, however if I long press - animation works. I've found some solutions, like setting type to .system, showsTouchOnHighlight = true, but none of them have helped. What is the problem here?
It's not a "problem" - it's by design.
When you have an object such as a button in a table view or scroll view or collection view, and you "touch" it, the system needs to know whether you are tapping the button or if you want to touch-and-drag to scroll the view that contains the button.
So, the table view (really, the "scroll view part" of the table view), waits to see if you drag your finger or not before it performs any actions.
If you want the button to respond immediately to a touch, you need to set
delaysContentTouches = false
on the containing scroll view(s).
If you search for uibutton inside uitableviewcell delaysContentTouches you should find plenty of discussion on this topic, and various approaches to change the default behavior.
For this problem you can add extension to UIButton and override some methods.
You can check my answer here

Touch Down firing in a weird way

I'm adding a touch down action to a uitextfield (actually it's a subclass, but I think that might not be important). I created a simple view controller and added this textbox to it, and wired up the event to println("Hello").
When I quickly tap the item (both in simulator, and on my phone) it works perfectly and says hello!
I then created a UITableViewController subclass, and in one of the static cells I added the same textbox.
In this case, when I quickly tap the textbox nothing happens! When I actually hold down the mouse or my finger for about 1/2 a second, it works. But not if I quickly tap it.
This is different from the previous textbox, which always works perfectly no matter how fast I tap it.
Are there some problems with different events being intercepted ors something of that sort?
I even went so far as to add a tap gesture recognizer to both the table cell, and the textbox, but neither work unless I hold it down (the table cell action won't even fire unless I click off the textbox and into the cell proper, of course).
Thanks so much this is very strange.
UIButton not showing highlight on tap in iOS7
and
iOS - Delayed "Touch Down" event for UIButton in UITableViewCell
have a lot of information about this. Apparently there is a delay for uitableviewcells that can be avoided by taking some of the approaches above.
I'll post the solution that works for me once I work on it. thanks!
EDIT OP DID DELIVER!! (lol sorry)
in IOS8, the idea is that table cells no longer have the uiscrollview that would basically delay the touching, so what you can do instead is something like this in your page did load:
for subview in self.tableView.subviews as [UIView]
{
if subview is UIScrollView
{
let scroll = subview as UIScrollView
scroll.delaysContentTouches = false
break
}
}
So see how we're iterating over self.tableview's subviews, and anytime we hit a scrollview set delaysContentTouches to false. This worked for me on both the simulator and on my phone.

iOS: Making only one UIView to respond

I have several UIViews (CollectionView, TextField, etc) in my ViewController. If the user presses any item in the collectionview, a new collectionview (smaller) is to be shown from the bottom.When the new collectionView is being shown, I want only this view to respond to touch events. If the user taps outside this view, it should be taken off the viewController. The functionality is similar to PopOverController. I am using
[subCollectionView becomeFirstResponder]
but the other views are also responding to touch events.
I wish I could put the question more clearly, Let me know if it is not clear.
Thx!
No need of setting firstResponder of a UIView.
All you need to do is
create a view named bottomAnimateView(which will come from bottm) of size =
self.view.frame and background color as clear color.
add a UICollectionView over it.
3.Add UITapgesture over bottomAnimateView and do the stuff of removing or hidding it from superView.
Refer the attachment .Which might help you.

iOS UITableView prevent from scrolling

I want to get information about how UITableView would be scrolled without actually schange scrollView.contentOffset. I cant use scrollEnabled property becouse its stop fireing scrollViewDidScroll event on table and I need it. Is there any way to do it?
The question is a little bit hard to understand but in any case scrolling on a UITableView will modify contentOffset. That's how the superclass, UIScrollView, works.
As for scrollViewDidScroll, it is only called automatically when the user scrolls the view, but you can override setContentOffset to trigger it manually when needed. Just to avoid a loop set a BOOL dragging = YES flag on scrollViewWillBeginDragging: and clear it on scrollViewDidEndDragging:willDecelerate:.

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