I've never run into this and can't seem to find anyone else talking about this. I have a simple tableview in a view controller. For some reason, the tableview doesn't allow any touches when it is moving. User can't select a cell or stop the motion of the scroll when it's scrolling. Anyone ever encountered this? Thanks in advance!
It sounds like you're doing something in a delegate method for UIScrollViewDelegate that is messing with the touch handling. Make sure you aren't blocking or doing anything otherwise weird in those methods.
Related
Edit: I am editing my initial question (see below for history) as I am getting new information.
I figured out that when the swipe motion starts from inside the button bounds, we never receive TouchesEnded or TouchesCancelled, only TouchesMoved. However, if I can react on WillEnddragging, it would be great. Is it possible to cancel a gesture on WillEndDragging and also pass this cancel down the children chain?
History:
I am using Xamarin Forms and I have the following issue
I have custom controls part of native scrolling views, like ScrollView or CollectionView, that remain in "clicked" state after the finger enters them but then initiates a scroll gesture.
I had a similar issue on UWP in the past and managed to solve it with the UIElement.PointerCaptureLost event.
Sorry if I am wasting your time on trivial stuff, but I am really stuck and I greatly appreciate your help.
I have tried different approaches suggested, including setting DelaysContentTouches to NO, and playing around with CanCancelContentTouches and overriding TouchesShouldCancelInContentView to always return NO, in a ScrollView custom renderer.
I have had a read of
Allow UIScrollView and its subviews to both respond to a touch
and
UIScrollView sending touches to subviews
Maybe the accepted answer here helps, but I am not sure how to get the tag of my custom view.
What I am expecting is my custom controls to receive the cancelled touch event (or something similar) as happens in both Android and Windows
This was easier than it looked. Solved by adding a UIGestureRecognizerDelegate to my UIGestureRecognizer class and in the delegate I overwrote ShouldRecognizeSimultaneously to return true.
I am doing paging effect in UICollectionView. My solution is shown below.
setContentOffset method will be called in scrollViewWillEndDragging and calculate the next or previous page contentOffset x value and set it with animation.
However, there is one issue which is that once the setContentOffset function has been called, if I touch the screen, then the scrollView will be stopped. Even if you release your finger, it won't continue, which means it stops at a wrong position.
Actually, I've tried to override the targetOffset in UICollectionViewFlowLayout but this issue still exists. Also, I tried to call touchesEnded but this is not even triggered at all. Furthermore, I tried isPagingEnabled and it won't cause this issue but my collectionView items are more complicated, which leads to a wrong targetContentOffset.
My current solution is set scrollView.isUserInteractionEnabled = false after setContentOffset and set it back to true when scrollViewDidEndScrollingAnimation called. This is okay but I am still wondering if there is any good way to do this?
I tried both Google Calendar and Outlook, they will reset you back to the position it should be.
I searched online and I cannot find any questions regarding this issue.
Could you help me? Thanks!
I tried a lot to figure it out and finally, I got something correct to share with you guys.
The solution is to set targetContentOffset in scrollviewWillEndDragging, then I can get what I want.
The truth behind this is that if you call setContentOffset, then scrollviewWillEndDragging won't be called in the second time endDragging (when you touch the screen after the first endDragging). However, if you simply set targetContentOffset = requiredContentOffset, then the second time endDragging will be called and at this time, the paging method will be called again to navigate UIScrollView to a correct position.
What I've learned from this is never call setContentOffset when you do the pagination effect. Some tutorials online for the pagination are totally wrong.
I have a super view that has a UITapGestureRecognizer on it. It allows touches within the view because there are clickable items within the view.
When these items are clicked on, I want to take a specific action, not the generic one that covers the entire superview. Unfortunately in my TouchDown event of my child control I don't know how to stop the event here. I know I could create a kludge flag, but this seems like the wrong way to go.
Any advice?
James
OK I got a solution. Totally my problem. I was playing around with trying to get all touches to work and at one point I had set cancelTouchesInView = true on the UITapGestureRecognizer superview. While this didn't stop the other touches from happening, for whatever reason the touches carried through to the superview as well. I understand that this explanation probably makes no sense, but that's what did it. Still trying to wrap my head around how iOS does touch.
So I have added a UIUITableView to a UIViewController. I can't use a UITableViewController for reasons I don't need to explain since it will be unnecessary information. Anyway, I have set the delegate, and the data source to this viewController. I've added the delegate and datasource protocols as well. The cells are populated correctly, so the datasource is working fine. I can also scroll so it all works fine.
However, I can't get the didSelectRowAtIndexPath to trigger. It SHOULD trigger, but doesn't. I've read and a lot of issues with this can be correlated to a UIGestureRecognizer, but I haven't implemented one. I also use the standard UITableView, so not a custom made one.
If I long press the cells (3-4 sec) then it gets triggered as it's supposed to. This suggests that there is some issue with another view or something absorbing the tap gesture, which I have no control over. How would I solve this?
No, it's not didDeselectRowAtIndexPath.
Yes all delegates and datasources are correct, since I can get the delegates/sources to trigger.
Yes, Single Selection is set on the TableView in the inspector.
Yes, everything has user interaction enabled.
If I just copy the code over to a UITableViewController it will work just fine, but right now that is not an option, I'm afraid. Anyone got any ideas on how to solve this? Most people who've had this issue has either had the issues in the list above, or added a UIGesture on top of the UITableView - I haven't.
I want to start by saying that I appreciate all the answers here provided, it gave me a lot of things to try out so I learned a lot - thanks! None of your suggestions worked, but simply because I'm a complete idiot. I said in the post that I did NOT implement a UIGestureRecognizerwhich I didn't...in that class, but in its super class. So I DID in fact implement it, but in a class that this ViewController was a subclass off. The only reason I didn't remember it was because I haven't looked at that super class for weeks.
Someone did suggest it in the comments that I should check for it, and I did and I was already certain I didn't implement one, so I quickly dismissed it. But now, after about 4 hours of debugging and recreating the project, adding things one by one, I eventually realized that the only thing that differed at this point was the Super Class, and the first piece of code I see when I open the file up was a GestureRecognizer...
So keep this in mind in the future everyone - I know I will. Thanks again for the help!
Sincerely,
The complete idiot.
Make sure you don't add any controller in that cell, which covers the entire cell and also the user interaction of that controller is enabled.
Due to that controller's user interaction enabled the tap action is taken by that controller and when you long press that cell, that cell will receive your tap.
Example :
UIView *_view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _cellWidth, _cellHeight)];
[_view setUserInteractionEnabled:YES];
[cell.contentView addSubview:_view];
In the above case that view got your tap instated of the cell.
I see a bunch of people asking about this on here, but I haven't seen any good solutions. Basically I want to detect when a user is done scrolling the table, and releases their finger. I don't want to do anything until their finger is off the screen or I think
scrollViewDidScroll would work. Any help would be amazing. Thanks!
UITableViewDelegate conforms to the UIScrollViewDelegate protocol, which provides the scrollViewDidEndDragging:willDecelerate: method.