UIScrollView not scrolling when touching some elements - ios

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

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.

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

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;
}

Forward vertical scrolls from UIScrollView to a sibling UITableView

I have a view controller with this hierarchy:
View Controller:
UIScrollView (scrollable horizontally)
UITableView (scrollable vertically)
I want to forward the vertical scrolls from my UIScrollView to the sibling UITableView, so that when the user scrolls up on the UIScrollView, the UITableView will scroll up instead. What would be the best way to do it?
I have tried these:
Detecting the vertical scroll in scrollViewDidScroll, it doesn't get called because the contentOffset of the scroll view does not change.
Subclassing the UIScrollView and overriding touchesMoved, I can't forward the touches to the table view because I don't have a reference to it in this class.
If the tableview is contained within the scroll view I believe you can set up the scroll view's gesture recognizers to respond only if the table view's gesture recognizers fail. I haven't had a chance to try this, but you should be able to set up a dependency between the gestures for each of the views.
UITableView* tableView = ...;
UIScrollView* scrollView = ...;
for (UIGestureRecognizer* r in scrollView.gestureRecognizers)
{
for (UIGestureRecognizer* tableRecognizer in tableView.gestureRecognizers)
{
[r requireGestureRecognizerToFail:tableRecognizer];
}
}
This will make your scroll simultaneously with UITableView and UIScrollView and apply #Stephen Johnson's block
- (BOOL)gestureRecognizer:(UIPanGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UISwipeGestureRecognizer *)otherGestureRecognizer
{
return YES;
}

UIScrollView inside UIPageViewController page scrolling issue

I have a situation - a UIPageViewController that has scrolling direction vertical. All of its pages are the same height as itself. And then inside each page I have a UIScrollView that also has scrolling in vertical direction.
The point of such an architecture is because i have news with some text between which i want to be able to switch with paging effect, but the news text can be bigger than the screen.
Now i got it all working good with one tiny issue. When you scroll the scrollView to the bottom it bounces (if you turn bouncing on) or just stops (if you turn bouncing off). And only after you lift your finger (stop the touches) you are able to switch to the next page in UIPageViewController.
What i would like to see is when you scroll to the bottom of the UIScrollView it automatically starts scrolling the UIPageViewController without you having to lift up your finger.
I expected that to be the natural behaviour. But its not in ios6 only in 7.
https://www.dropbox.com/s/noua5jo5trv5kn1/iOS%20Simulator%20Screen%20shot%20Sep%2029%2C%202013%207.08.03%20PM.png
https://www.dropbox.com/s/m0965bff5h4eq21/iOS%20Simulator%20Screen%20shot%20Sep%2029%2C%202013%207.08.11%20PM.png
implement UIScrollViewDelegate imside your UIViewConroller
something like
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y == scrollView.contentSize.height) {
if (self.nextPageNeededHandler) {
self.nextPageNeedeHandler();
}
}
}
and block in your .h file
#property (nonatomic, copy) void (^nextPageNeedeHandler)(void);
set property like
...
__weak MyPageViewController *self_ = self;
nextPageVC.nextPageNeedeHandler = ^{
[self_ goNextPage];
};
...

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