iOS Programming Autorotation, Popover Controllers, and Modal View Controllers

iOS Programming Autorotation, Popover Controllers, and Modal View Controllers?

自动旋转,Popover 控制器,Modal view controller?

1.?

In this chapter, you are going to make four changes to Homepwner‘s behavior that will tailor the app‘s behavior to whatever device it is running on.

你将做四个改变,不论在哪个设备上运行:

(1)On iPads only, allow the interface to rotate when the device is upside down.

只在iPads,允许interface 旋转当设备一边朝下
(2)On iPads only, show the image picker in a popover controller when the user presses the camera button.

只有在iPad 的情况下,当用户按came‘ea button 时,才展现image picker 在一个popover Controller 中。
(3)On iPads only, present the detail interface modally when the user creates a new item.

只有在iPads下,才展现detail interface modally当用户创建new item时。
(4)On iPhones only, disable the camera button in the detail interface when the device is in landscape orientation.

只有在iPhones,不允许一个camera button 在detail interface 当设备是landscape 方向时。

?

2 Autorotation

There are two distinct orientations in iOS: device orientation and interface orientation.

在iOS 中有两个不同的orientations: device orientation and interface orientation.

The device orientation represents the physical orientation of the device, whether it is right-side up, upside down, rotated left, rotated right, on its face, or on its back.

device orientation 代表了device 的物理orientation ,它是否正面朝上,朝下,左转,右转。

You can access the device orientation through the UIDevice class‘s orientation property.

你可以通过UIDevice类的orientation? 属性来获取。

The interface orientation, by contrast, is a property of the running application.

?interface orientation对应的是运行的程序的一个属性。

The following list shows all of the possible interface orientations:

(1)UIInterfaceOrientationPortrait

The Home button is below the screen. ? home 按钮在屏幕的下面

(2)UIInterfaceOrientationPortraitUpsideDown

The Home button is above the screen. ? home键在屏幕的上方

(3)UIInterfaceOrientationLandscapeLeft

The device is on its side and the Home button is to the right of the screen. 设备在边上,home 键在屏幕右边

(4)UIInterfaceOrientationLandscapeRight

The device is on its side and the Home button is to the left of the screen.? 设备在边上,button 键在屏幕的左边

When the application‘s interface orientation changes, the size of the window for the application also changes.

当应用的interface orientation 改变了,application 的窗口的大小也就发生了改变。

The window will take on its new size and will rotate its view hierarchy. The views in the hierarchy will lay themselves out again according to their constraints.

window会采用新的size,并旋转它的view hierarchy。这些views 在hierarchy就会再次根据constraints 来布局他们自己。

Open Homepwner.xcodeproj and build the application on the iPad simulator.

While Homepwner is running on the simulator, you can simulate a rotation

Navigate to the BNRDetailViewController.

From the simulator‘s Hardware menu, select Rotate Left option.

从模拟机的Hardware 菜单,选择? Rotate Left 选项,

The simulator window will rotate, causing your "device" to rotate its window and contents.

?

When the device orientation changes, your application is informed about the new orientation.

当你的device orientation 改变时,你的应用被告知新的orientation .

Your application can decide whether to allow its interface orientation to match the new orientation of the device.

你的应用能决定是否允许你的interface orientation 匹配新的设备orientation.

You can change which interface orientations an application supports in the same editor where you universalized Homepwner.

你可以改变哪个interface orientatons 一个应用支持

?

In the Target information‘s General tab, look at the Device Orientations section for iPad. Notice that the portrait and the two landscape options are selected, but Upside Down is not. Click on the Upside Down button to toggle it on

技术分享

Now, the interface will rotate in all directions. It is typical that an iPad application can rotate to all four orientations while an iPhone application can rotate in any orientation other than upside down.

Some applications will want to lock the user to a specific orientation.

一些应用程序可能想把用户锁定在一个给定的方向上。

For example, many games only allow the two landscape orientations, and many iPhone applications will only allow portrait.

比如:一些game仅仅允许两个landscape 方向,许多iPhone应用仅仅允许portrait。

Toggling these buttons will allow you to choose which orientations are valid for your application.

选择这些按钮可以让你选择你想让你的应用程序在哪个方向上有效。

In addition to the application choosing which interface orientations are acceptable, the view controller that is occupying the screen also gets a say.

处理application 能选择哪个‘interface能接受外,占据了屏幕的? view controller 也可以。

Each view controller implements a method that returns all of the interface orientations it supports.

每个view controller 实现了一个方法将返回所有它支持的interface orientations .

For the interface orientation to change, both the rootViewController of the application and the application itself (per the Supported Interface Orientations section of the info property list) must agree that the new orientation is OK.

对于改变interface orientation , rootViewController的应用和application itself 必须接受新的orientation 是可以的。

By default, a view controller running on the iPad will allow all orientations.

默认情况下,在iPad 上的view Controller允许所有的orientations.

A view controller on the iPhone application will allow all but the upside-down orientation.

在iPhone 上的view controller 除了upside-down orientation 之外,允许所有的方向。

If you would like to change this, you must override supportedInterfaceOrientations in that view controller.

如果你想改变,你需要重写supportedInterfaceOrientations在这个view Controller中。

The default implementation of this method looks like this:

?

- (NSUInteger)supportedInterfaceOrientations

{
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {

return UIInterfaceOrientationMaskAll; }

else {

return UIInterfaceOrientationMaskAllButUpsideDown; }

}

?

?for some reason, your root view controller wanted to appear in landscape left or landscape right only, it could implement the method as follows:

- (NSUInteger)supportedInterfaceOrientations

{
// On all devices, return left and right
return UIInterfaceOrientationMaskLandscapeLeft

| UIInterfaceOrientationMaskLandscapeRight; }

?

If you want the view controller being displayed by the UINavigationController to determine the autorotation mask, subclass UINavigationController and override it:

如果想让你的view Controller 别展示通过UINavigationController决定autorotation mask,UINavigationController的子类并重写它:

@implementation MyNavigationController

- (NSUInteger)supportedInterfaceOrientations

{
return self.topViewController.supportedInterfaceOrientations;

}

@end

UITabViewController asks the view controller for each of its tabs for its supported interface orientations and returns the intersection: That is, the UITabViewController only supports an orientation if all its tabs support it.

UITabViewController 要求view Controller 为每一个tab 支持的interface orientations 并返回焦点:这是,如果它的tabs 支持。

?

2 Rotation Notification?

There will be times when you want to do something special in a view controller when the device orientation changes.

有时候你希望当device orientation 改变时,在view Controller里做些特别的事情。

In Homepwner, one issue is that on an iPhone, the UIImageView on the BNRDetailViewController becomes too small in landscape orientation.

It would make more sense to limit the user to taking and viewing the picture in portrait orientation.

限制用户只能在获取和展示图片在portrait orientation 是有意的。

To make this happen, you need to hide the image view and disable the camera button when the application is in landscape orientation.

当用户在landscape orientation 时,隐藏image view和不让camera button 有用是有用的。

First, you need a pointer to the camera button so that you can send it a message to disable it.

Control-drag from the camera button on the toolbar to the class extension area of BNRDetailViewController.m to create a weak property outlet named cameraButton. This will create and connect a new property:

@property (weak, nonatomic) IBOutlet UIBarButtonItem *cameraButton;

When writing code to respond to a change in orientation, you override the UIViewController method willAnimateRotationToInterfaceOrientation:duration:.

当你写代码来响应orientation 的改变时,你可以重写UIViewController方法:willAnimateRotationToInterfaceOrientation:duration。

The message willAnimateRotationToInterfaceOrientation:duration: is sent to a view controller when the interface orientation successfully changes.

willAnimateRotationToInterfaceOrientation:duration消息会发送给view Controller 当interface orientation 成功的改变的时候。

The new interface orientation value is in the first argument to this method.

新的interface orientation 是该方法的第一参数;

In BNRDetailViewController.m, create a new method called prepareViewsForOrientation: to check for the device and then check the interface orientation. If the device is an iPhone and the new orientation is landscape, hide the image view and disable the button.

Call this method when the view first comes on screen and again whenever the orientation changes:

调用该方法在view 第一次出现和orientation 改变的时候。

?

- (void)prepareViewsForOrientation:(UIInterfaceOrientation)orientation

{
// Is it an iPad? No preparation necessary
if ([UIDevice currentDevice].userInterfaceIdiom ==

UIUserInterfaceIdiomPad) {

return; }

// Is it landscape?
if (UIInterfaceOrientationIsLandscape(orientation)) {

self.imageView.hidden = YES;

self.cameraButton.enabled = NO; } else {

self.imageView.hidden = NO;

self.cameraButton.enabled = YES; }

}

?

- (void)willAnimateRotationToInterfaceOrientation: (UIInterfaceOrientation)toInterfaceOrientation

duration:(NSTimeInterval)duration

{
[self prepareViewsForOrientation:toInterfaceOrientation];

}

?

- (void)viewWillAppear:(BOOL)animated

{
[super viewWillAppear:animated];

UIInterfaceOrientation io =
[[UIApplication sharedApplication] statusBarOrientation];

[self prepareViewsForOrientation:io]; ...

When you write code that changes something about a view (like its frame or whether it is hidden) in this method, those changes are animated.

当你写代码来改变一个view时,这些改变是动画的。

The duration argument tells you how long that animation will take.

duration 参数告诉你animation将持续多长。

?

If you are doing some other work on rotation that does not involve views, or you just do not want the views to animate their changes, you can override the willRotateToInterfaceOrientation:duration: method in your view controller.

当你做一些工作不涉及到view后者不想要animate时,你可以用willRotateToInterfaceOrientation:duration: method在你的view Controller 中。

This method gives you the same information at the same time, but your views are not automatically animated.

这些方法给你了相同的信息,但是你的view不会自动动画。

Additionally, if you want to do something after the rotation is completed, you can override didRotateFromInterfaceOrientation: in your view controller.

如果你想在旋转之后做一些事情,你可以重写didRotateFromInterfaceOrientation在你的view Controller中。

This method‘s argument is the previous interface orientation before the rotation occurred.

这个方法的参数是你在rotation 发生之前的interface orientation。

?

3.UIPopoverController?

A popover controller displays another view controller‘s view in a bordered window that floats above the rest of the application‘s interface.

一个POPover Controller 显示其他view Controller 的view在浮在应用interface上的边界窗口。

It is only available on iPads.

它只能在iPad上有。

When you create a UIPopoverController, you set this other view controller as the popover controller‘s contentViewController.

当你创建一个UIPopoverController ,你设置其他的view Controller为popover? controller的contentViewController .

Popover controllers are useful when giving the user a list of choices (like picking a photo out of the photo library) or some extra information about something that is summarized on the screen.

当提供给用户一列选择时(从photo library 中选择一个photo)或者一些额外的消息。

For example, a form may have some buttons next to some of the fields. Tapping on the button would reveal a popover whose contentViewController explains the intended use of that field.

例如,表格中有一些button,临近一些field。点击button将会出现一个popover ,它的contentViewController 解释了这个field如何使用。

In this section, you will present the UIImagePickerController in a UIPopoverController when the user taps the camera bar button item in the BNRDetailViewController‘s view

?

In the class extension in BNRDetailViewController.m, declare that BNRDetailViewController conforms to the UIPopoverControllerDelegate protocol.

@interface BNRDetailViewController () <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate>

?

Additionally, add a property to hold the popover controller.

?

@property (strong, nonatomic) UIPopoverController *imagePickerPopover;

In BNRDetailViewController.m, add the following code to the end of takePicture:.

?

// Place image picker on the screen

// Check for iPad device before instantiating the popover controller

if ([UIDevice currentDevice].userInterfaceIdiom ==

UIUserInterfaceIdiomPad) {

// Create a new popover controller that will display the imagePicker

self.imagePickerPopover = [[UIPopoverController alloc]?initWithContentViewController:imagePicker];

self.imagePickerPopover.delegate = self;

// Display the popover controller;?sender

// is the camera bar button item

[self.imagePickerPopover ? ?presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny

animated:YES];

} else {

[self presentViewController:imagePicker animated:YES completion:nil]; }

?

?

?

?

?

?

?

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。