I am drawing with multiple colors by dragging fingers on the iPhone app but when I minimize the app and then maximizes, I am losing all my drawing as it calls the drawrect method. I don't know from where this method is being called but I am not able to see any solution to this problem. Mainly it is happening when I am running many apps on the device. I think the iOS deletes all the data in the buffer in order to prevent low performance of the iPhone. What is the solution to this issue? And why it is losing the drawing? Please help! I didn't find any solution of this problem.
Because your view is unloaded in the background , and when you are back to the foreground , the view will be recreat , so it will redraw.
When you enter background , if the device memory is low , Apple will unload the background app`s view(even close your app) , to enlarge the memory for the current running app. Your view is unloaded , when you be back to foreground , the view will recreat by the "data" , so make sure do not hold the "data" in the view.
And maybe in IOS6 , Apple modify the mechanism
I am losing all my drawing as it calls the drawrect method.
From your Question, it seems as if you are not drawing in your drawRect method,
drawrect method is called every time your view is updated / loaded. So when you enter from background drawrect method is called. If you are not handling in your drawing mechanism in drawrect method, you loose all data.
Apple States that
The default implementation of this method does nothing. Subclasses
that use native drawing technologies (such as Core Graphics and UIKit)
to draw their view’s content should override this method and implement
their drawing code there. You do not need to override this method if
your view sets its content in other ways. For example, you do not need
to override this method if your view just displays a background color
or if your view sets its content directly using the underlying layer
object. Similarly, you should not override this method if your view
uses OpenGL ES to do its drawing.
If you are handling it other ways then you need to handle that after your view is drawn on in viewwillAppear.
Else there can be memory reason, since if you get memory warning, ViewDidLoad is called where you generally initialise data.
The framework will call drawRect as needed, it is your responsibilty to draw the view when it is called. You should be storing whatever state you need from the users actions in order to redraw the view whenever drawRect is called.
Related
The way my app currently deals with orientation is it repositions all of the items in the view, the layout of which can change as the user interacts with it. I've had numerous problems, such as view's not appearing, views changing before the screen rotates etc. I'm wondering the best way to deal with orientation?
If the landscape-layout is completely different from the portrait-layout I just load all subviews in the init-method of my UIView-subclass and added them as subviews.
The whole magic is done in the layoutSubviews-method where I only check in which orientation I am at that moment. Never call alloc, addSubview, removeFromSuperview, ... methods in layoutSubviews. The layoutSubviews should only contain code that sets the frame-properties of subviews.
Referring to your problems:
view not appearing: maybe forgot an addSubview-call
views changing before the screen rotates: you probably update some frame-properties of subviews outside the layoutSubviews-method
One possibility - if your app only works with one orientation, disallow orientation changes. This is a reasonable response, some apps are only usable in one view.
I want to create a scroll view with a massive contentSize that will display content inside it. The content will be mostly text (a few small images will be drawn for content-boundaries).
So, think like a tiled map application, but tiling labels instead of tiled images.
Performance is critical in this application, so I think I should avoid using UILabels or any UIViews at all inside the scroll view.
How can I draw these labels as the user scrolls around? Some options I've considered:
override drawRect: in the scroll view and draw everything within the window - this seems like it would be really slow. Sometimes drawRect is called with only a 1 pixel difference.
Same, but keep track of which ones I've already drawn
Draw them from the "outside" somehow, like from the scroll view delegate - I can't figure out how to use [#"mystring" drawInRect:] outside of drawRect: (context problems)
Is there something I haven't thought of? I know the scroll views were designed to be able to handle this kind of problem, but I'm not sure what the designed way is. Thanks!
The standard way to achieve this in an iPhone application is to create a normal UIScrollView that is the size you want it to be, and to populate it either directly with a CATiledLayer if you're feeling brave or with a custom UIView subclass that uses a CATiledLayer and implements - (void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context.
CATiledLayer provides the same experience as Safari — it's good for views that are much larger than the screen and which are expensive to render, but which you don't want to ruin the fluidity of the user experience. It'll request tiles as and when it needs them on a background thread, then fade them in (according to a fade of any length, so you can cause them to appear instantly if you desire) when they're ready. If your program really can always keep up with the scrolling and you've requested an instant appearance then there'll be no evidence that there's an asynchronous step involved.
An example people tend to point to is this one, but if you're new to implementing your own UIView subclasses then it might be worth seeing e.g. this tutorial. Then look into the + layerClass property on UIView and the various properties of CATiledLayer (which I think you'll also possibly need to subclass since + fadeDuration is a class method).
My iphone application has a user form under UIViewController.
When I out of application (go to background mode) and start application again some of my UIView changes its positions and sizes. (These UIViews depend on keyboard position)
Definately somewhere is my fault.
I try to figure what is going on when application starts again from background and where the UIView changes can be done.
May be you can suggest any links to read.
Thank you.
The UIViewController's viewDidLoad and viewWillAppear methods get called every time the view is dumped from memory, something that commonly happens when the app goes into the background. Depending on your code, it's possible that you're storing some position data that's not getting cleared. If that's the case, you can either:
Change your code to better fit the Model-View-Controller pattern so that the positioning code and variables are all in the controller, and you appropriately clean things up in its 'viewWillDisappearandviewDidUnload` methods (the better way), or
Clear out whatever remnants are hanging around in your application delegate's applicationWillEnterBackground method.
I discovered that my drawRect is being called more than once. Unfortunately this had the unfortunate side-effect of double-drawing everything because all my subviews are drawn in drawRect (I'm s strict atheist w.r.t. Interface Builder).
What is the best way to deal with a multiple calls to drawrect? A flag to check if it's being called again? Or clear the whole view and redraw from scratch (as I have done?)
What do you mean by "your subviews are drawn in drawRect"? If you mean that you're putting calls to -addSubview: in your drawRect, don't. Move those to a more appropriate place that gets called only when it needs to (probably the -initWithFrame: method for your view if the subviews are always there), and use drawRect only to do custom drawing.
Strictly speaking, being called multiple times is the entire point of -drawRect. It's called to update small parts of your view when needed. It's actually called quite often if you're updating your view (moving it around, updating the superview, etc.), so it should be as simple and fast as possible to avoid performance problems.
When UIKit calls drawRect:, the graphics context set up to draw into should already be cleared for you (unless you have set the clearsContextBeforeDrawing property to NO). Are you perhaps calling drawRect: manually instead of calling setNeedsDisplay/setNeedsDisplayInRect:?
Also, each view is responsible for drawing only its own content and not the content of its subviews.
I have some custom drawing code in drawRect which also performs some calculation of sizes.
When is the earliest I can be sure that this code has been loaded, e.g. if I want to modify it's containers size accordingly?
-[NSView viewWillDraw] is a reasonable place for last minute layout.
I have some custom drawing code in drawRect which also performs some calculation of sizes.
When is the earliest I can be sure that this code has been loaded, e.g. if I want to modify it's containers size accordingly?
An object can't exist until its class is fully loaded. If you have an instance, the class that it's an instance of is completely loaded, because you wouldn't have an instance of it if it wasn't.
As for when it's called: It's called when you need to draw. This normally happens as part of the event loop, if anything has marked the view as needing display. It is possible to directly tell an NSView to display, but, as far as I can tell, this is not possible for UIViews.
So, if you need to do something to it before it gets told to, either do it immediately after creating it or, if you're about to set the view as needing display, do it before you do that.
Just before the view is displayed or when you call
[aView setNeedsDisplay];
I just created my first customView app. This was one of my questions. my drawRect method was called once upon creating my window (or recreating). And millions of time when resizing my window.