How to rearrange views during autorotation in iPad - iphone

A view controller has six rectangular views. In landscape mode, I want to arrange them 3 columns and 2 rows. But in portrait mode, I want to arrange them 2 columns and 3 rows.
How do I implement it when iPad rotate between landscape and portrait?
Do I need to have two nib files: one for landscape with 3 columns and 2 rows and the orther for portrait with 2 columns and 3 rows, and swap them during autorotation?
Or something else? What is the best way to implement this? Thanks.

You only need 1 nib file. Create IBOutlets for your columns/rows and then manually set them in:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
You will want to make sure to call willRotateToInterfaceOrientation in your viewWillAppear also to make sure that the initial position of your columns/rows are set correctly when you enter the view in landscape mode.

Perhaps you want to look at UICollectionView. It might work for you. Otherwise, you should look at using autolayout. If you use two nibs you can use UIViewControllers methods such as
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation;
Alternatively, layoutSubviews is called when the device rotates and you could perform any manipulations there.
I think if the differences are fairly minor then you should not need to use two different Nibs.

You can do it with 2 xibs, or if you're using layout constraints, you can set it up in portrait mode (in IB), then in code save those constraints to an array in viewDidLoad. In the willAnimateRotationToInterfaceOrientation:duration: method, create new constraints for the landscape orientation and add them to the superview. Check out my answer to this question, UIView to Ignore Orientation or Stick-To-Bottom Container for an example of how I've done this.,

Related

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.

iOS views presentation

Im new with iphone programming and im facing issues with the views.
I can not respent the view properly, for example in this case. I have an ViewController with a tabbar at the bottom. This controller have other 4 controllers where i show each of them when a user clicks on the icons.
But when a new view from one of the 4 controllers appears on the main controller, i get a line under the view. In the picture is a purple one.
When i change orientation, this empty line appears in the same place. Some times, when i enter with landscape orientation in the app, this line appears at the left.
I'm working here with IB. so, can someone point me here to the right direction? :S
On shouldAutorotateTo.. method i have YES, do i have to manage the views and change size and place every time the method is executed?
do i have to create 2 NIB for each controller, being one for each orientation option??
edit: i changed the picture to be more clear and show other "bug".
On 1 i enter to the view on portrait orientation. change it and still having a wear line up stares. All my nibs are on portrait orientation and 320 and 480 size.
On 2 i enter to the view on landscape but the nib loads as portrait. When i change orientation, it does not expand at it should.
How do i fix this 2nd issue?
i don't fill like having 2 nibs per controller :S
Thx in advance !
Short answer for Your autorotation problem:
You can either create two nibs (and switch between them, when autorotation occurs), or use just one nib. This depends on your goal. If you want to create a totally different view (like music app shows cover flow on landscape, and song on portrait) you should create two nibs.
If your view is more like the message app you could easily use just one nib. Take a look at the "Size Inspector" (5th tab in Xcode 4), the red lines guide you. The apple documentation for Xcode 4 interface builder is a good start to get you into that behavior.
That space in your view looks like the exact height of the status bar in iOS, review your NIBs in IB to see if you have a simulated status bar for your view controllers. If you do, turn it off and you will likely see that your view is not sized right. Being that it's height is 460 rather than 480.

How do i make orientation work in my app?

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.

iPhone orientation management : what is the most efficient way to do?

I need to develop an iPad application which should manage the two orientation mode (landscape and portrait).
According the official Apple iOS documentation, there are 2 ways to proceed.
-The first one consists in adjusting views element when the rotation event is received. The main advantage is that we had only one ViewController
-The second one consists in displaying a specific ViewController for each orientation. Therefore, we have 2 ViewControllers.
The second approach seems to be nice, but I'am afraid by the numbers of ViewController that will be needed. What's more, the "data synchronisation logic" in the ViewControllers will have to be duplicated (or isolated from the ViewController) to be used in both orientation.
The application I need to develop will contain many "full custom elements" and many ViewControllers.
If anyone has advices or experience feedback, it would be really appreciated ;)
Thank's for reading !
The second way should rather be: using 2 different views (one for portrait, one for landscape) and swapping the view controller's view in willRotateToInterfaceOrientation:. No need to duplicate your data logic.
Which way to use? I would say: it depends.
If the lanscape and the portrait modes differ only by the position / size of views, I use the first one (plus you'll get nice animations of the frame changes)
If landscape and portrait are too different, I prefer the second one.
I usually solve this by taking advantage of the autoresizing techniques in the view combined with the implementation of willAutorotateToInterfaceOrientation and willAnimateRotationToInterfaceOrientation methods in the view controller.
With autoresizing techniques you can easily resize standard UI elements provided by Apple. If your UI elements doesn't have an impossible layout, you can apply the autoresizing techniques to them too. You must set the autoresizesSubviews property to YES in the parent view controller and select an autoresizing behaviour for each subview. For example, if you want it to resize to the right maintaining the view centered, you can apply the autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin mask in the subview.
If the autoresizing techniques doesn't do the trick, then you will need to resize each conflicting view separately by implementing the - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration in your view controller. If you have "full custom elements", you will need to resize them this way.
In my particular experience, I prefer to have only one view controller and one view for all orientations and manage them with these two techniques.
Hope this helps you!

If I'm building a custom view inside of Interface Builder, do I need to have two different NIB files, one for Portrait and one for Landscape?

I'm building a custom view inside of Interface Builder that has buttons with image backgrounds. The buttons extend to each side of the screen, so I'll need two images for each layout (Portrait and Landscape). As such, do I need to have two different NIB files for each layout (Portrait and Landscape), or is there a way to just use one NIB file and specify which images to use for the buttons depending on which layout the app is running in?
Thanks so much in advance for all your help!
You should use 1 nib file. Give each control the correct autoresizingMask to ensure they scale and position correctly when the orientation changes.
Changing the images should be done in the view controller by overriding one of these methods:
willRotateToInterfaceOrientation:duration:
willAnimateRotationToInterfaceOrientation:duration:
didRotateFromInterfaceOrientation:
More info about these methods are in the docs.