How does the UIScrollView delegate know about my UIScrollView ivar? - iphone

I'm working on a app that has a paging UIScrollView that contains three scrollViews as subviews which display images that you can pinch and zoom on. The code came from Apple's "PhotoScroller" sample code but I've stripped out the tiling functionality because I'm trying to master the basics first.
I can zoom in on my different images and page through them, which is great. When I leave an image that has been zoomed in to go to the next "page" of the pagingScrollView I want it to be restored to it's original zoom size, right now it stays at the zoom level that I left it at.
I imagine I need to write some code that tells the zoomed UIScrollView to go back to the appropriate zoom scale when I get to the next page. My question is how do I do that?
So far I've been working with UIScrollView's Delegate method "scrollViewDidScroll" and and the "contentOffset" property. Another thought is somehow getting a notification that the pagingScrollView has moved to the next "page."
Any ideas?

If you're interested in knowing when the scroll view has stopped (e.g. the user has let go and the scroll view has snapped into position on a new page) you can use scrollViewDidEndDecelerating:. However, the user may scroll several pages before allowing the scroller to fully stop, so the last page the user stopped on may not be the immediately preceding or immediately following page. You can keep a pointer to the current page and each time the user stops on a page restore the previously current page to the default zoom level before updating the current page pointer.

Related

How to prevent UIScrollView to scroll through two pages?

I have UIScrollView and i'm using it in pagingEnabled mode. In this UIScrollView,i've many images to load.So it's impossible to load all of them. I decided to load five by five. Initially, i load five images and set their position,size and tags. So far, i'm able to do this.
Once user arrives fourth page, i need to set sixth page and remove first page from superview. For that, I'm using this method to do that.
[[self.scrollView viewWithTag:currentPage-3] removeFromSuperView];
To detect page changed event properly, i've used almost all of the delegate methods of UIScrollView, but when users scrolls continuously, i've missed pages. So, i cannot load images properly. For example,when i missed to load page 6, i cannot load page 8.
I tried to disable userInteraction mode, even if it's set to NO,user can continue scrolling.
What i want to do is,when user did page changed, i want to disable UIScrollView to scroll until i finished loading images into UIScrollView.
Do you guys have any idea,how can i accomplish that ?
Thank you.
What i want to do is,when user did page changed, i want to disable UIScrollView to scroll until i finished loading images into UIScrollView.
If you want to disable scrolling after each page scroll, look to the UIScrollViewDelegate methods, like scrollViewDidScroll:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScrollViewDelegate_Protocol/Reference/UIScrollViewDelegate.html#//apple_ref/occ/intf/UIScrollViewDelegate
Within scrollViewDidScroll: you can set scrollEnabled on the UIScrollView to NO. Once you're images finish loading, re-enable scrolling through the same property.

UIScrollView - how to get rid of delay before scrolling?

I'm using a UIScrollView to display a custom UIView. When the user drags a finger across the UIScrollView, there is a noticeable delay before the display begins updating. If the user keeps touching the screen, the UIScrollView becomes very responsive after a short time. Subsequent attempts to scroll result in the same initial delay, followed by high responsiveness. This delay seriously affects the usability of the view and I would like to get rid of it.
In a test project I have written to try to get to the bottom of this issue, I have only been able to partially replicate the behaviour. The first time that the user scrolls is exactly the same - however any subsequent attempts to scroll are responsive straight away.
I have tried both setting delaysContentTouches = NO and subclassing UIScrollView so that touchesShouldBegin returns NO as suggested in multiple places online, but neither has worked.
I'm using MonoTouch on iOS 4.3, but Objective-C answers are fine. I would post code to help illustrate the issue, but since I have been unable to narrow down the problem this would be well over 1000 lines. Hopefully this is enough info to get a solution.
Does anyone know what might be causing this delay, and how I can get rid of it?
Some general suggestions for improving scrolling performance.
Have your scrolling views rasterize offscreen:
myView.layer.shouldRasterize = YES;
Set that property for each sub-view on the scrollview - do not set it for the children of those sub-views or you just eat up memory that way.
If your scrolling views do not need compositing, make sure you turn that blending off:
myView.opaque = YES;
Test using the simulator by leveraging these two features that appear on the Debug menu of the iOS Simulator:
Color Off-screen Rendered
Color Blended Layers
If that doesn't address your problem, and you have implemented UIScrollViewDelegate, double-check to make sure you are not doing anything time consuming in those methods - for example, based on your description, you might be doing something in scrollViewDidScroll, scrollViewWillBeginDragging, or scrollViewWillBeginZooming and if you are, optimize that so it happens before scrolling even begins. Also, make sure you're not doing anything in touchesBegan.
I suspect what is happening is there is some kind of interaction enabled in the content of your scroll view.
The system does not know if the initial touch down is going to be a tap on one of the subviews or a drag on the scroll view, therefore is causing a delay while it waits to see if you are going to lift your finger.
What are the subviews of the UIScroll view?
As an experiment set all the subviews of the UIScrollView to have userInteractionEnabled = NO, this will not be what you want, but its just a test. Is should scroll fine after this, otherwise I am wrong.

Displaying one graph per day, home screen style

I'm working on an app that can display a graph with some data, one every day. I'll call this "dayGraph".
I'd like to build an interface similar to the iPhone home screen, aka pageControl, with one dayGraph per page. (but i don't need the small dots!)
I tried with the standard pageControl example from Apple, and it's working, but only with a small number of pages. I need to display even 100 possible dayGraph, if the user wants, but the pageControl is going crazy when the page number exceed 50.
I know that the photo app is doing a similar thing, and it can work with many photos.
My question is: How can i do that? Is there any "Apple way" of doing it, or i should begin to make my own method for swapping the dayGraphs?
Thank you very much!
If your goal is to enable swipe-based paging, the view you want to use is a UIScrollView. Set its pagingEnabled property to YES. Then add each graph as a subview of your UIScrollView, setting the frame of each graph to position each one on its own page extending beyond the bounds of your UIScrollView to the right. Finally, update the contentSize property of your UIScrollView to encompass all of your pages.
Now the user can swipe left and right to flip between the pages of your scroll view.
Note: If you add 50+ subviews to your scrollview, it's likely that you'll run into memory problems. To avoid this, you'll probably want just keep subviews loaded for the current page, plus the adjacent pages to the right and left. Set a delegate on your UIScrollView to an object that implements scrollViewDidEndDecelerating:. In that method, remove any subviews that aren't on the current or adjacent pages, and make sure each adjacent page has its subview loaded. That way you'll never have more than 3 pages of content in memory at one time.

UIScrollView with embedded UIWebView not scrolling after holding

I have a UIWebView which is embedded in a UIScrollView. The webView is resized so that the scroll view manages all the scrolling (I need control over the scrolling).
In the webView I have disabled userSelection via '-webkit-user-select: none;'
Everything is working fine except one annoying detail. When I hold down my finger on the content before starting to scroll for about a second the scrollView won't scroll. My best guess is, that it has something to do with userSelection. The time is about the same it usually takes for the copy/paste/magnifying-thing to appear which usually disables scrolling as well.
I am running out of ideas on how to solve this. Every help would be greatly appreciated!
Thanks!
EDIT: Another aspect of the problem is, that the non-scrolling actually triggers JS-Eventhandler (click, mousedown, mouseup) inside my webView which leads to surprising app behavior. The user puts her finger down, waits, scrolls, nothing happens, removes her finger and this is perceived as a click, which feels wrong from a users perspective.
I would guess what is happening is that after that short duration, the scrollview is no longer interpreting the touch as being on it's view and instead passes the touch down to it's content views.
Have you tried delaying the content touches for the scrollview? This will essentially tell the scrollview to delay taking action on the touch event and instead to briefly monitor the touch and if the touch moves then it recognizes it as a swipe gesture for scrolling. If it doesn't move, it will eventually pass the touch along to it's subviews.
scrollView.delaysContentTouches = YES;
I think even then, there is a standard delay time before the scrollview will pass the touch events along the responder chain. If you hold for too long, it's going to naturally perceive it as being a press down event rather than a scroll event.
This question is not relevant anymore. As of iOS 5.0 the UIWebView is based on a real UIScrollView and also exposes that UIScrollView via a property. Use that instead.
And don't mess with UIWebViews embedded in UIScrollViews anymore. The documentation explicitly advises against that.
Relevant Documentation

Nested UIScrollView-iPhone photos application

I have been facing the same nested UIScrollView problem for long time.I tried some open source codes like Scrolling madness ,three-20 and others but all fails finaly.I am trying to make a photo Viewer application same as iPhone.For that I have created the structure like this:-
1)one View controller.
2)on view of view controller one UIScrollView (i.e inner/parent scroll view) as a child.
3)on inner/parent scroll view number of child scroll views(i.e. outer/child scroll views) ,each represents one page of photos application.
4)On each scroll view one image View on which i am displaying my image.
So what I want is when user scrolls the outer scroll view it should scroll horizontally with all the child views so I will get the look and feel of paging in photos application.Also when user is on one specific image(i.e. child/outer scroll view) he should be able to zoom in/out,swipes and perform single/double tapping.I was able to make it work in sdk 2.1,but it dosnt work since sdk 3.0.Please tell me the idea behind your project.Means which scroll view you are subclassing ,in which view to detect touches.How this completely child - parent relation should be.
If possible provide any sample code also.
There is a WWDC session from 2010 that deals with this very issue.
Here's the short of it:
You need a single scroll view that is paginated and scrolls horizontally. Each "page" of that scroll view is another scroll view containing a photo.
First, it looks like you want to subclass UIScrollView? Every interaction method you need is provided for you in either the delegate callbacks or the touch methods. (Many of Apple's more advanced classes, such as UIScrollView, react poorly to subclassing.)
Second, it sounds like you have a first responder problem. IOW, your innermost scrollview isn't getting the first crack at the touch events.
Andrew
I also struggled with this for a long time trying samples you mentioned. I could finally figure it out with the samples provided by apple (iphone dev center).
http://developer.apple.com/iphone/library/samplecode/Scrolling/Introduction/Intro.html
http://developer.apple.com/iphone/library/samplecode/ScrollViewSuite/Introduction/Intro.html
The first one is pretty basic and probably what u already have. The second one is all about zooming, etc. Just study these and the samples you already have, I think you will be able to figure it out. On specific topics just come back here search for answers or post another question.
EDIT: I forgot this one check out these examples by Andrey Tarantsov hosted on github. This is what you want... http://github.com/andreyvit/ScrollingMadness