UITableView (inside UIScrollView) didSelectRowAtIndexPath: not being called on first tap - ios

I have a non scrollable UITableView inside an UIScrollView. And I'm having the problem that when I touch a row, the callback didSelectRowAtIndexPath: is not being called on the first tap, but after the first tap everithing works.
A few considerations:
After the first tap, the table view works normally, every tap works in every cell.
This happens just after I scroll the UIScrollView. If I don't scroll the UIScrollView, this never happens.
I have overriden the UIScrollView's touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view and the event does pass throw here, the view is a UITableViewCellContentView effectively.
I just don't know why the event is not been sent to the UITableView on the first time, and on the following ones it does.

If you have UIScrollView that contains vertical content and UITableView as part of this content, you must at least disable scrolling on UITableView - otherwise it's confusing for the user when he will scroll your mainView and when tableView, and also confusing for the framework because it's not clear where to send panning gestures.
As a rule of thumb - you should avoid putting table views inside scrollViews, unless you really know what you're doing.

Please disable scrolling of your table view and check the datasource and delegate are connected to your table view. If not follow the bellow code
#interface myClass ()<UITableViewDataSource, UITableViewDelegate>
- (void)viewDidLoad {
[super viewDidLoad];
self.myTableView.scrollEnabled = NO;
self.myTableView.delegate = self;
self.myTableView.dataSource = self;
}

Related

Can not perform swipe-to-delete on UITableView if it is in UIScrollView

I have created a UITableView that can perform swipe-to-delete on its table cells in normal cases, but when I put the UITableView into a UIScrollView that can be horizontally scrollable, the outer scrollview will swallow the swipe event, thus the swipe-to-delete is not workable.
I'm sorry to tell you that you have to give up one for your function since the two functions rely on the same gesture.
If you want to keep the swipe-delete, set the outer scrollview.scrollEnabled = NO. I think that would help.
If not, have a button to start the tableview edit mode. That will make you delete cell with the scrollview can be slided.
I've finally found solution!
Subclass the outer UIScrollView, and override a method
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
#interface AllowSwipeScrollView : UIScrollView
#end
#implementation AllowSwipeScrollView
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
BOOL inTableViewCell = .... // check the current touch is in table view cell
if (inTableViewCell) {
return NO;
}else{
return [super gestureRecognizerShouldBegin:gestureRecognizer];
}
}
#end
And make sure the UITableView instances are in AllowSwipeScrollView.
try This condition
if (ScrollView == self.tableView) return;
in scrollviewdidscroll method.

UIScrollView not scrolling when touching some elements

I have a UIScrollView with Autolayout on, and several elements on it. The problem is that when I try to scroll touching over some elements nothing happens, but when I try to scroll touching over some other elements the scrolling works perfectly.
The UIScrollView has several UIViews with UITextfields and UIButtons inside.
It seems that the touch events, or scrolling events, are not being sent to the parent UIScrollView, but just for some views.
Any thoughts?
UIScrollView has a method -(BOOL)touchesShouldCancelInContentView:(UIView *)view that by default returns YES if view is not a UIControl object; otherwise, it returns NO. So if you want to enable scrolling when touching UIControl objects you should subclass from UIScrollView and override touchesShouldCancelInContentView: to return always YES:
#interface MYScrollView : UIScrollView
#end
#implementation MYScrollView
- (BOOL)touchesShouldCancelInContentView:(UIView *)view
{
return YES;
}
#end

Forward tap-gesture to superview of UICollectionViewCell

I have a UITableView where each UITableViewCell contains a UICollectionView. The UICollectionView has UICollectionViewCells.
My problem is: Some of these UICollectionViewCells should react to tap-gestures, others should forward the event to the UITableViewCell (so it triggers displaying of the detail-view for that UITableViewCell).
I've been studying the apple-docs and several questions here but I can't get it to work.
(I think it should be possible to solve this generally, but just in case: Each UICollectionViewCell contains an UIImageView.)
Suggestions are very appreciated.
If I understand you correctly, you can do it like this:
Set cell.userInteractionEnabled = NO on the cells you don't want to handle events.
Override hitTest in your UICollectionView with this method:
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *hitTest = [super hitTest:point withEvent:event];
return hitTest == self ? nil : hitTest;
}
So tapping anywhere outside of a cell with user interaction enabled, super returns the collection view and we return nil, causing the table view cell to handle the event.
Why don't you let only the uicollectionview cell's handle the taps and then in the callback determine what action to take. For some you could do what you do now when tapping the cell, for others whatever you want.

Make Keyboard Disappear when UITableView Scrolls

I have a UITextField at the top of my Table View, after the text field is selected I want the keyboard to disappear. I know to call [[self view] endEditing:YES]; but I don't know how to check for the scroll. A good example of this is IMessage, when the keyboard is in view you can scroll up to collapse it, I want my table view to work inversely.
UITableView is a subclass of UIScrollView. By being the table delegate (implementing <UITableViewDelegate>) you are also the scroll view delegate (<UIScrollViewDelegate>) and as such you can implement:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
Then you will receive a notification whenever the table view is scrolled. You can then also use scrollView.contentOffset to check where the table has scrolled to (which direction it's scrolling in).
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
[textField resignFirstResponder];
}
Try other method in UIScrollViewDelegate if you need other behaviour.
Call resignFirstResponder where appropriate.
It seems you use UITextField in your cells. Use UITextFieldDelegate protocol to know when UITextField ends being edited:
-(void)textFieldDidEndEditing:(UITextField*)textField
{
[textField resignFirstResponder];
}

UITableView in UIView in UIScrollView. When scrolling tableview don't scroll scrollview too

I have a UITableView inside a UIView inside a UIScrollView.
Problem: when i scroll/drag the tableview, the scrollview scrolls too.
What i need is for the tableview not to pass the scroll to the scrollview. Also i need to be able to use the scrollview when i scroll it directly.
How can i do this?
Cheers
I fixed it using "hitTest" on the tableview.
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
If the event originated within the tableview, i disable the parent's scrollview scroll.
And, when the tableview's scroll has ended (scrollViewDidEndDragging) i re-enable the parent's scrollview scroll.
This seams to work fine.
Set a delegate to your tableview's scrollview (i.e your view controller)
tableView.scrollView.delegate = self;
then use those two calls
– scrollViewDidScroll:
– scrollViewDidEndDragging:willDecelerate:
to disable and re-enable your outside scrollview's scrollEnabled property

Resources