iPhone: Best way to handle 400 UILabels in UIScrollview - iphone

I've been working on a crossword app for a while. The actual game runs in a UIScrollview, because the player should be able to scroll, zoom and pan.
To the UIScrollview i added a UITapGestureRecognizer that handles the touch-event, and calculates where the player touched. So far so good.
Afterwards I added about 400 UILabels to the UIScrollview. Each of them are "empty" until the player presses a button on the keyboard. My problem is that when i add these labels the whole UIScrollview become very slow and laggy in scrolling etc.
As the user guesses the right words green tiles will become visible. The tiles are loaded in as UIImageViews. This reduces the performance again.
I have looked at DTGridView, but I've got no luck with it.
Can you please help me out and try to guide me in the right direction?

i think you should implement the UIScrollview method drawRect you self instead of add 400 UILabel in it
you can set a NSArray contains 400 objects called "label";
when user pressed the button, you should calc the postion & test of the "label" &decide which "label" should display in the scrollview in current offset .
add 400 UILabels in one UIScrollview may cause the memory problem;

You need to use recycled label in your scrollview. That will improve the performance. To know how to reuse/recycle subviews in UIScrollView please check Apple WWDC videos on UIScrollView. WWDC 2010 Sample Code . Also check UIScrollView Class Refference UIScrollView Class Reference
You can get help from this link Creating Circular and Infinite UIScrollViews

I've been playing with this for the past while/days even. Using various related answers. But eventually I used instruments and a bit of commenting to see what was slow.
I remember someone saying layoutSubviews slows things when you addSubviews, so I took my "Local" code out of there. But nothing sped up.
So when using a breakpoint during my addSubview routine, I noticed the iOS system was actually in a superview's layout calls (navigationCtrlr) during viewDidLoad.
I introduced a 0.1 second delay before adding subviews and bam! I recommend dispatch_async to prevent crashes from race conditions, but that's another subject.
In short, it might be in LayoutSubviews even if you don't think you are there.

Related

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.

iPhone UIScrollView Continuous Circular Scrolling

I have found similar questions here but none of them are answered. So please help me..I have a UIScrollView with five UIImageView as contents. No paging is there for the scroll view. I need to display the images in a continuous manner and allow the user to scroll infinitely without any jerk in a circular manner. So when the user scrolls to the right, after the last image, the first image should come and the scrolling should continue in the natural way. Similarly if the user scrolls left, after the first image, the fifth image should appear. I used didEndDeceleration but it will apply a sudden break to the scrolling giving a distortion to the user experience. Also, surprisingly, it is not called at the end of the scroll every time. I am now trying to override the setContentOffset of the UIScrollView by subclassing it. The result was better than didEndDeceleration but the sudden break is still there. Please help me..
Thanks in advance.
Apple's Street Scroller demo from their UIScrollView presentation at WWDC 2011 should give you enough info to get this done. I also recommend watching the video. Has a lot of good stuff.

UIImageView in UIScrollView

I have a series of UIImageViews in a UIScrollView. The user can zoom into each one, but after a bit of usage the images start disappearing, and then various images in the app disappear. I'm wondering if anybody has any any experience with this and has any idea why this could be happening?
Its a complete guess until you give us source, but chances are that you are doing something like not retaining your image views or are adding them to another view – effectively removing them from the first view they were in.

Rearrange subviews in UIScrollView like App-Icons on Home-Screen

Hej folks,
I got a question to you: I got a UIScrollView in my application containing numerous subviews (all direct subclasses of UIView). Now I want to give the user the possibility to rearrange these subviews inside the scrollview. Is there anyway to make it look like the way we all can change the icons on our homescreen (auto-rearrange)? I would really appreciate any help!
Thanks in advance,
Tim
Unless you use some custom tool kit (I'm not sure there exists a custom tool kit or API to achieve this), I think you should create them from scratch.
I'm also creating very similar thing you said. In an UIScrollView instance, I added small subviews and can order them only vertically by dragging. Also, I can take any subview to the outside of an UIScrollView instance. (a little bit tricky)
There are two ways to build them. (small subviews == icons)
1a) Implement touch events(gestureRecognizer or touchesBegan, Moved, Ended, Canceled) in a main subview of UIScrollView that contains many small subviews.
1b) Implement touch events in each small subview.
I chose 1b because I want to use small subviews not only in UIScrollView but also anywhere in my program. But with 1b, it was a little bit hard to prevent multitouch among these small views. Also I felt that with 1b, touch events in small subviews are more free from the complicated responder chains of an application.
2) Create a NSMutableArray instance that contains a list of small subviews.
3) Implement a function that displays a NSMutableArray instance onto a main view of an UIScrollView instance by enumerating it.
4) Implement a function that enumerates a NSMutableArray instance and checks whether a current touch position of small subview is in a frame of any small subview of a NSMutableArray. (or checks whether a current moving small subview's frame interesects a frame of any small subview) You can use CGRectContainsPoint or CGRectContainsRect functions from CGGeomtery.
5a) If yes, then you can just change frame of every small subview of a NSMutableArray.
5b) If the user releases a finger outside of frame of any small subview, then do nothing.
Simply using block-based animation methods(iOS4 and later) or begin/commit animation methods, you can create them like a home screen.
Very Good Example For Scrollview with Pagecontrol like iphone home Screen
https://github.com/jarada/myLauncher

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