首页 » iOS编程(第4版) » iOS编程(第4版)全文在线阅读

《iOS编程(第4版)》17.2 自动转屏通告机制

关灯直达底部

当设备方向发生变化时,可能需要在视图控制器中执行一些操作。例如,Homepwner应用目前存在一个问题:当应用在iPhone中运行,并且界面处于横排方向时,BNRDetailViewController中的UIImageView对象会显得非常小,如果限制用户只能在竖排方向拍摄和浏览照片,用户体验会更好——可以隐藏UIImageView对象并禁用相机按钮。

首先,为了禁用相机按钮,需要创建一个指向相机按钮的插座变量。打开BNRDetailView- Controller.m,同时,在辅助编辑器中打开BNRDetailViewController.xib(在项目导航面板中按住Option键并单击BNRDetailViewController.xib)。

现在,按住Control键,将UIToolbar中的相机按钮拖曳到BNRDetailViewController.m的类扩展中,创建弱引用的插座变量cameraButton。Xcode会自动生成如下代码:

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

接下来的任务是:当应用在iPhone中运行,并且界面处于横排方向时,隐藏UIImageView对象并禁用相机按钮。

如果需要在界面方向发生变化时执行某些操作,则可以在UIViewController中覆盖willAnimateRotationToInterfaceOrientation:duration:方法。在界面方向发生改变后,UIViewController会收到willAnimateRotationToInterfaceOrientation: duration:消息,消息的第一个参数是新的界面方向。

在BNRDetailViewController.m中创建一个新方法:prepareViewsForOrientation:,如果设备类型是iPhone,同时界面方向处于横排方向,就隐藏UIImageView对象并禁用相机按钮。接下来,当BNRDetailViewController的视图出现在屏幕上,以及界面方向发生变化时,调用此方法:

- (void)prepareViewsForOrientation:(UIInterfaceOrientation)orientation

{

// 如果是iPad,则不执行任何操作

if ([UIDevice currentDevice].userInterfaceIdiom

== UIUserInterfaceIdiomPad) {

return;

}

// 判断设备是否处于横排方向

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];

在iPhone模拟器上构建并运行应用。在BNRDetaileViewController中为BNRItem添加一张图片,然后将iPhone模拟器旋转至横排方向。可以发现添加的图片消失了,同时相机按钮也会变为灰色,无法点击。接下来将iPhone模拟器旋转至竖排方向,此时消失的图片会再次显示在屏幕上,相机按钮也可以点击了。如果在iPad上运行应用,图片会一直显示,相机按钮也始终可以点击。

如果在该方法中编写修改视图属性的代码(例如修改视图的frame或通过hidden显示/隐藏视图),则方法会自动为属性的变化过程添加动画效果(例如由大变小或淡入淡出)。duration参数表示动画的持续时间。如果在应用转屏时不需要对视图做处理,或者不需要使用属性变换的动画效果,也可以将该方法替换为willRotateToInterfaceOrientation: duration:。两个方法将会在转屏时同时调用,参数的含义也都是相同的。但是,willRotateToInterfaceOrientation:duration:方法中不会自动添加任何动画效果。

此外,如果需要在转屏完成之后执行一些操作,则可以在UIViewController中覆盖didRotateFromInterfaceOrientation:方法。该方法的参数是发生转屏之前的界面方向。最后,UIViewController对象有一个interfaceOrientation属性,表示该对象的当前界面方向。

本节编写了针对iPhone的特定代码,下一节将为另一种设备添加新功能——如果应用运行在iPad中,则会通过UIPopoverController显示UIImagePickerController。