How do i make orientation work in my app? - iphone

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.

Related

Get the current UIView's ID objective-c iphone

How can I get the current UIView's ID so that I can use it later without using an IBOutlet?
I would like to add an image over the top of my app but I'm switching views frequently and would like to be able to add the image to the current view because it would show up in my second view
Thnx in advance.
You can't access a UIView by ID in the way that you can on Android devices. IBOutlets are the equivalent for connecting graphical layouts to code.
Based in your comment, the appropriate thing for you to do is to be adding the overlay view at a higher level in the view hierarchy. If you have two views that could be displayed at any given time, and you want to make sure you can cover either of them regardless of which is in place, add your overlay view to the superview of those two. This works all the way up to using the UIWindow object that your App Delegate has, which will let you overlay on top of everything (this is essentially how UIAlertViews work, for example.)
You could set the UIView's tag attribute. Then you can reference it from the superview with
- (UIView *)viewWithTag:(NSInteger)tag

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.

When in the view reload resources when orientation changes?

I have view that have many subviews, and each have it's own graphics, different for portrait and landscape orientations. When should I load the new graphics when the orientation changes?
If shouldn't be layoutSubviews, I don't also like the idea of reloading resources in view from UIViewController, because of complicated view hierarchy that I have (it would require to pass this information down).
There is also option to register in NSNotificationCenter for orientation changes in each view, and load new resources when it changes. But I don't quite like it either, because I believe that there should be mechanism in iOS that enables that. Or, maybe I should think in a different way, and build different views for portrait and landscape...
What do you suggest?
I would have your subviews all extend a custom view class that has a -setOrientation: method that swaps between the portrait and landscape graphics. Then in your view controller I would override -willRotateToInterfaceOrientation:duration: and add a loop that sets the orientation for all of the children, thereby causing the graphics to swap when the orientation changes.
I think that's the most straighforward way to do it. Using NSNotificationCenter could be tricky and you're left without a guarantee that every child will get the notification.
Anyway, that's how I'd do it. Let me know if you need examples.

iPhone - subview stacking slowing down application?

As title says, I'm wondering if stacking subviews can slow down an iPhone application.
For example, I have a UIViewController, which has a view occupying the whole screen. When the user presses a button, I create a second view controller and add its view as a subview of the original VC, making the second view completely hide the first one.
Does the application have some kind of automatic optimization which would be something like "ok, I know what to draw for every pixel of the screen, I stop seeking for subviews" ?
If not, I don't think stacking 2 full-screen views can really slow down the app, but could 3, 4 or more views be problematic if they include many subviews themselves (labels, images)?
Read the View Controller Guide sections on Modal View Controllers and memory management. Prefer to use modal Views instead of subviews when you want to present a new screen temporarily and a UINavigationController for "drill-down" views.
You can always set UIView#hidden = YES on the views not seen. That should prevent redraws.
This is largely dependent of what the subviews contain and what is the total memory load of the app. Memory is very crucial for devices like iPhone and you should never keep the things which you don't require. When you are adding many subviews without releasing any, your memory requirement obviously will increase. This may slow down the app, even may crash the app. Stacking of two may not be a problem, but stacking many is not a very good design.
So the summary is you should always check the memory load of the app through instrument and always properly respond to memory warnings.

Making view transitions fast - do you use this hack?

I have an iPhone app that displays a modal view controller. The modal view controller shows two instances of a custom subclass of UITextView called RoundedTextView, an MKMapView, and a UIToolbar. I construct the viewController only once, and reset its data and present it each time the user summons it.
When showing this view controller with presentModalViewController, I noticed that the animation to show the view was choppy on the 3G. So, to speed it up, I set the alpha of the MKMapView and the two RoundedTextView objects to 0 on viewWillDisappear and back to 1 on viewDidAppear. This made it nice and fast. I also presume that I could remove the views from the superview to speed it up as well.
Does anyone else jump through these kind of hoops on the iPhone. Is there something else I should be doing to avoid this hack?
It's not a hack to simplify drawing during animation in order to make the animation more smooth. It is indeed a very valid technique.
You may be able to achieve similar performance improvements by setting all UI elements to Opaque, a technique also used to fix table view cell performance issues. You just have to make sure background colors match.
The main problem I had was I subclassed UIButton to make gradient buttons and I had the boundary mask enabled. This made the performance terrible. I removed that option and made my buttons square and it's blazin now.