📜 ⬆️ ⬇️

Autorotation of complex interfaces in programs for iPad

Most programs for the iPhone and iPod touch only support portrait orientation. Many developers did not even think about adding landscape (landscape) orientation where it is really needed. Apple, which in iPhone OS 2.x did not provide the best examples, is not an exception, without realizing support for landscape (landscape) orientation in important system programs (in iPhone OS 3.x, the company corrected its mistake).

With the advent of the iPad, the situation has changed. Apple has obliged all developers to support all orientations of the device in programs for the iPad. Naturally, there may be exceptions, for example, games. But programs that do not have a hard binding (functional) to orientation should be user friendly in any position of the device.

There are no difficulties with simple interfaces. Objects of the UIView class are assigned the necessary autoresizingMask property, which describes the frame change. This method is no longer suitable for complex interfaces.

I will tell you how to make a smooth and pleasant autorotation of the program interface using the layoutSubviews method. Get detailed information about this method in the iPad Programming Guide . I just give you a real, practical example of its use (Apple’s documentation is stingy in this regard).
')
This is one of the options, but the result of his work is very high quality. Naturally, this option is suitable for iPad and iPhone / iPod touch.

Suppose we want to have the following portrait and landscape (landscape) views:



Immediately post the final draft of RotateDemo .

And video:


Let's create a basic project for iPad (Window-based).

I used to do the whole interface programmatically. If you want, you can easily replace a part of the code with a mouse click in Interface Builder.

Add the ContainerView class files (derived from UIView) to the project. Leave it empty for now. An object of this class will be a container of all UIView objects in our controller. It is in this class that we will reassign the layoutSubviews method.

Create class files DemoViewController (derived from UIViewController).

Our interface file DemoViewController.h:

#import <UIKit/UIKit.h>
#import "ContainerView.h"

@ interface DemoViewController : UIViewController
{
ContainerView *containerView;
}

@end

* This source code was highlighted with Source Code Highlighter .


In the class implementation, only one main loadView method is important to us:

- ( void )loadView
{
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];

UIView *contentView = [[UIView alloc] initWithFrame:screenRect];
contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
contentView.backgroundColor = [UIColor blueColor];
self.view = contentView;
[contentView release];

containerView = [[ContainerView alloc] initWithFrame:CGRectMake(0, 0, screenRect.size.width, screenRect.size.height)];
containerView.backgroundColor = [UIColor blueColor];
containerView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[self.view addSubview:containerView];

UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button1.frame = CGRectZero;
[button1 setTitle: @"Object 1" forState:UIControlStateNormal];
button1.tag = 1001;
[containerView addSubview:button1];

UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button2.frame = CGRectZero;
[button2 setTitle: @"Object 2" forState:UIControlStateNormal];
button2.tag = 1002;
[containerView addSubview:button2];

UIButton *button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button3.frame = CGRectZero;
[button3 setTitle: @"Object 3" forState:UIControlStateNormal];
button3.tag = 1003;
[containerView addSubview:button3];

UIButton *button4 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button4.frame = CGRectZero;
[button4 setTitle: @"Object 4" forState:UIControlStateNormal];
button4.tag = 1004;
[containerView addSubview:button4];
}

* This source code was highlighted with Source Code Highlighter .


Everything is simple here. We create a container and add all our items to it. In the example, these are just 4 UIButton buttons. The frames of the buttons have no meaning (they will be set in the layoutSubviews method).

Go back to our ContainerView class and override the layoutSubviews method:

- ( void )layoutSubviews
{
[super layoutSubviews];

if (self.frame.size.width == 768)
{
UIView *view = [self viewWithTag:1001];
view.frame = CGRectMake(184, 100, 400, 150);

view = [self viewWithTag:1002];
view.frame = CGRectMake(184, 300, 400, 150);

view = [self viewWithTag:1003];
view.frame = CGRectMake(184, 500, 400, 150);

view = [self viewWithTag:1004];
view.frame = CGRectMake(184, 700, 400, 150);
}
else
{
UIView *view = [self viewWithTag:1001];
view.frame = CGRectMake(74, 100, 400, 150);

view = [self viewWithTag:1002];
view.frame = CGRectMake(550, 100, 400, 150);

view = [self viewWithTag:1003];
view.frame = CGRectMake(74, 400, 400, 150);

view = [self viewWithTag:1004];
view.frame = CGRectMake(550, 400, 400, 150);
}
}


* This source code was highlighted with Source Code Highlighter .


The example uses a comparison with absolute width. Alternatively, you can use the universal check:

if (UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))

* This source code was highlighted with Source Code Highlighter .


Is done. It remains only to activate our controller in the delegate class:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
controller = [[DemoViewController alloc] initWithNibName:nil bundle:nil];
window.backgroundColor = [UIColor blueColor];
[window addSubview:controller.view];
[window makeKeyAndVisible];

return YES;
}


* This source code was highlighted with Source Code Highlighter .


So we got a smooth animation of changing a complex interface when changing orientation. Minimum code and nothing complicated.

Source: https://habr.com/ru/post/95028/


All Articles