26

If you scroll down a bit at this Apple Developer Page you'll find the section "Creating an Alternate Landscape Interface". The basic approach described there is to present a different NIB file as a modal view when orientation changes. I am using the Storyboard feature, so I don't have NIBs. How do I load a different "scene" in that case?

Besides that, I am using a Tab Bar controller, I don't want to show a modal view. I just want to replace the current portrait view with a landscape view designed with interface builder and keep my tab bar. What would be the Storyboard way to achieve the task "Creating an Alternate Landscape Interface"? Thank you.

Korbi
  • 1,438
  • 4
  • 15
  • 22

3 Answers3

20

When you add a view controller to the storyboard it comes with a view. Call that the container view. Add two views to the container view: a portrait view and a landscape view. Set the dimension of the portrait view and the landscape view appropriately using the size inspector. Add buttons, more views, labels or whatever to the portrait and landscape views as needed for your application. Then when the orientation changes hide one view and show the other.

T.J.
  • 3,942
  • 2
  • 32
  • 40
  • 1
    interesting approach. Will try that. Thanks – Korbi Jan 15 '12 at 14:31
  • 5
    What if you use IBOutlets, those can only be assigned to only one view. – Sebastian Hoffmann Feb 13 '12 at 08:31
  • 1
    @Paranaix I may not completely understand your comment. The original question poses a requirement to have different interfaces for landscape and portrait mode. If you are looking for a different layout for the same interface that is a different problem. Maybe you should pose a completely new question. – T.J. Feb 13 '12 at 13:42
  • I'm trying to do this, but I can't seem to add a second view to a standard view controller. Is there something else that one needs to do? – GreenKiwi May 18 '12 at 05:49
  • @BenHolland, this solution uses fundamental view properties so it should work with all version of Xcode. – T.J. May 22 '12 at 23:31
  • @TJ What Paranaix is asking is that only ONE IBOutlet can be set for items such as buttons. Therefore, you would have to create separate outlets for everything. With a basic view with a few items it is not a big deal, but with an extensive number of items this could be labor intensive. This is the issue I am facing now. – Christopher Jun 12 '12 at 22:52
  • I find this solution, at least, very dirty. You are duplicating all your buttons etc., and have to make different Outlets... – cprcrack Oct 05 '12 at 01:19
  • I can't connect more views to the container view only one view , please could you please give me example for portrait view & landscape view – wod Dec 31 '12 at 07:13
  • 1
    How i can <<< Add two views to the container view >>> only storyboard allow to add one embed relationship .Please could you help me – wod Dec 31 '12 at 11:19
  • @Paranaix You can use IBOutletCollection to have many IB views connect to one code point – Paul de Lange Mar 29 '13 at 15:17
  • No this not the best solution, I have a big project use this methodology but when the storyboard contain huge views this will make your Xcode hung also your Mac.I think we should find another solution rather than two views in same scene – wod Jul 17 '13 at 08:27
  • I understand what to done, but can somebody make some tutorial or some pictures how to do it ? Please. My problem is how to do it efficient. So far as I see it I need to hide one view, and then change orientation back, and again back also. Is this correct ? Or am I doing something wrong ? Please. – WebOrCode Apr 14 '14 at 17:09
  • How can "Add two views to the container view:"? – Ibrar Ahmed Feb 20 '15 at 19:11
3

You can setup a navigation controller and one main view. Then you can use a template view for the portrait and landscape layouts (2 additional views).

You will need to setup the controls on the main view and make sure each one has a unique tag. Your main view will not be used, instead you will copy the controls to the two template views and set them up based on how you want each view to look. The benefit to this is each view will retain its tag which becomes a very important piece of this implementation.

Doing this you use a hybrid approach in regards to writing some UI code and using Interface Builder. After getting the two templates setup, create a unique identifier for each one. You will have to write some logic to handle the view and its subviews. A recursive method to return a collection of these based on the template you choose.

The core logic in the root view controller implementation will need to check for isPortrait and based on this you will want to load the correct view based on the identifier.

Experiment with this concept and see if it works for you. The main benefits to not using two separate views with unique controls (not the shared approach with same tags) is that you maintain access to your original subviews. Any instance variables you define in your view controller that points to a text filed, label, etc... continue to do so regardless of which template view is used. This maintains the model, view, controller approach as the data structure remains unchanged.

Using this approach you can still maximize the use of interface builder, and layout the templates for each view, while still having the flexibility to to write some custom UI code if you desire. Using only interface builder can be a bit limiting at times, and writing custom code based on orientation locks you in to a bit of tedious work.

Hope this helps some.

ttosh
  • 73
  • 6
1

You can make a xib file that contains 2 uiviews, one fore portrait and one for landscape. Assign as file's owner of the xib, the same viewcontroller of the view thet you have in the storyboard. In viewDidLoad load the xib file, and add the appropriete view for portrait or landscape.

So if you have a storyboard with many viewcontrollers, you can set the two possibility (portrait or landscape view) only in the viewcontrollers that you are interested to change the orientation.

I used this solution and work very fine !

mattiad
  • 13
  • 1
  • 6