Disable taps on UIScrollView - ios

I would like to disable the effect of the UIScrollView, that it cancels the current setContentOffset animation when tapped. However, panning should still be recognized at any time.
The reason is that I have implemented custom page-sizes (By using the UIScollView delegate's method - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset, where I set targetContentOffset, such that it is a valid page bound).
If a user now taps while an animation is going on, the UIScrollView cancels the animation, which I want to avoid, because it leaves the UIScrollView with an invalid contentOffset.

There's a UIScrollViewDelegate method, scrollViewDidEndScrollingAnimation:, which tells you when a scroll view animation caused by calling setContentOffset:animated: completes. I ended up setting scrollEnabled to NO on the scroll view before I call setContentOffset:animated, then setting it back to YES in scrollViewDidEndScrollingAnimation:. Effectively the user can't tap to cancel the scroll animation.

Related

What is difference between scrollViewWillBeginDecelerating: and scrollViewDidEndDragging:willDecelerate:?

scrollViewWillBeginDecelerating: delegate method is called on finger up as it is moving.(from UIScrollView.h)
But, scrollViewDidEndDragging:willDecelerate: delegate method is also called when same state.
(called on finger up if the user dragged. decelerate is true if it will continue moving afterwards) -> from UIScrollView.h)
When I test, they are always called together.
I don't know what is the difference.
Actually, I should know when a scroll will be begun deceleration.
scrollViewWillBeginDecelerating: is always called on finger up.
No both has differrent states
scrollViewDidEndDragging - The scroll view sends this message when the user’s finger touches up after dragging content. The decelerating property of UIScrollView controls deceleration.
scrollViewWillBeginDecelerating - The scroll view calls this method as the user’s finger touches up as it is moving during a scrolling operation; the scroll view will continue to move a short distance afterwards. The decelerating property of UIScrollView controls deceleration.
Refer Here
If you drag the scroll view so slowly that after your finger is up, the scroll view won't move, then scrollViewDidEndDragging:willDecelerate: will be called, with decelerate == NO, while the scrollViewWillBeginDecelerating: not being called.
Both the delegate methods will be called when you drag fast enough.

how to response to touchupinside event in a UIScrollView?

I have a UIScrollView in the centre of the whole view which is separated in to three parts and scroll horizontally.
Users can scroll the view freely and when the finger is up, i want to set one of the three parts to show based on the contentoffset of the UIScrollView.
how could i detect the touchupinside event in the UIScrollView? I tried add UITapGestureRecognizer and override touchesEnded but it does not work.
How about instead using the - scrollViewDidEndDecelerating:?
Keep in mind that just because the user has picked up their finger doesn't mean that the scrollview has stopped changing its content offset. By utilizing the - scrollViewDidEndDecelerating: delegate method, yo will be notified when the scroll view has come to a stop and at that point you can check the contentOffset and do what you need.
- scrollViewDidScroll: isn't a good match for what you want as it gets called even while the user's finger is still down. If that is important to you, then use - scrollViewDidEndDecelerating: as I mentioned above. If you'd rather know when the finger is lifted, and don't care that the scrollview is still in transit, then you can use - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate.

UIScrollView Zoom on shake effect

I am working on application in which i need to zoom the scroll view on shake effect so user will not touch the screen to pinch or double tap.
I have implemented the code by looking in to this tutorial:
Zoom UIScrollView with multiple images
I got the call in a delegate:
viewForZoomingInScrollView
But the image view not zoom in or out.
When i touch the screen after the delegate called the scroll view is zoom in. But content in scroll view not zoom in or out. It remains as it is.
Even some time i did not get call in the following delegate:
scrollViewDidZoom
scrollViewDidEndZooming
So do i need to call layout subview after viewForZoomingInScrollView if yes where?
From my understanding the view is not zooming because i have not pinch or double tap the scroll view.
Please help me out.
Those you mentioned are UIScrollView delegate methods and they are called when the scrollView will\did actually zoom, not to perform the zooming.
To perform the zoom programmatically you need to use zoomToRect:animated: and passing the portion of your scorllView's subview you want to scroll and wether it needs to be animated or not.
Hope it helps.

Cancel UIScrollView bounce animation after didEndDragging?

I have a horizontal UIScrollView. I want to implement a custom animation instead of the default bounce, where I pull all the way past the right edge of the scroll view's content size, the scroll view fly back to (0, 0) content offset after releasing finger.
Is there a way to cancel the bounce animation, keep the content offset from resetting, and then perform my animation?
I found a solution to this problem. Just use the UIScrollView delegate method:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
Thinking extemporaneously, without testing in code, grab the contentOffset, then set it back with setContentOffset:... animated:NO. That should cancel the ongoing animation and transition instantly to the position given. Since the position given is the current position, it should just cancel the animation.

UIScrollView.contentSize seems to grow with zoom

So the contentSize of my scrollView is initially equal to the frame of my image, but it seems that the more I zoom, the larger the contentSize gets. Thus, when the scrollView is zoomed in, , there is a huge gap around it. Dynamically updating the contentSize in - (void)scrollViewDidZoom:(UIScrollView *)aScrollView doesn't seem to work. Am I missing something?
Note: the gap is only visible vertically (i.e: above and below the imageView)
I don't believe it is possible to update contentSize on the fly while zooming. This is because:
A scroll view also handles zooming and panning of content. As the user
makes a pinch-in or pinch-out gesture, the scroll view adjusts the
offset and the scale of the content. When the gesture ends, the object
managing the content view should should update subviews of the content
as necessary. (Note that the gesture can end and a finger could still
be down.) While the gesture is in progress, the scroll view does not
send any tracking calls to the subview.
(Apple docs)
You should update your contentSize based on zoomScale after the user has finished zooming using:
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView
withView:(UIView *)view
atScale:(float)scale

Resources