61
UIPopoverController Modal View Controller 范圣刚,[email protected] , www.tfan.org

13 UIPopoverController and Modal View Controller

  • Upload
    tom-fan

  • View
    1.010

  • Download
    10

Embed Size (px)

DESCRIPTION

UIPopoverController 和 模态化视图控制器

Citation preview

Page 1: 13 UIPopoverController and Modal View Controller

UIPopoverController 和 Modal View Controller

范圣刚,[email protected], www.tfan.org

Page 2: 13 UIPopoverController and Modal View Controller

•截⾄至⺫⽬目前我们已经看到了有四种⽅方法可以⽤用来显⽰示⼀一个 view controller 的 view:

•第⼀一种是可以设成 window 的 root view controller,view 就变成了 window 的 subview

•第⼆二种是把 view controller 压⼊入⼀一个 UINavigationController 的堆栈

•第三种是我们可以把它添加到⼀一个 UITabBarController

•以及模态化的把它呈现出来

Page 3: 13 UIPopoverController and Modal View Controller

•在这个主题我们来看⼀一下 UIPopoverController, 以及更多⽤用来呈现模态化 view controller 的选项

•有些选项只对 iPad ⽣生效,我们第⼀一步先把 Homepwner 改成 universal appication - 就是可以本地化的在iPad,以及iPhone,iPod touch上运⾏行

Page 4: 13 UIPopoverController and Modal View Controller

Universalizing Homepwner

•Device -> Universal

Page 5: 13 UIPopoverController and Modal View Controller

改进界⾯面的两种⽅方式•改成 Universal 之后,ItemsViewController 视图在

iPad 上看起来很好,但是如果选择⼀一⾏行的话,可以看到 DetailViewController 的界⾯面可能需要⼀一些加⼯工(⽽而且轻击获取图⽚片的按钮会抛出异常,后⾯面⻢马上会纠正这个问题)

Page 6: 13 UIPopoverController and Modal View Controller

•改进 DetailViewController 界⾯面效果的⼀一种⽅方法是设置 autosizing mask,让他的 iPad 上⾃自动调整来适合 iPad

•另外⼀一种是创建两个完全独⽴立的 XIB ⽂文件,⼀一个针对 iPhone,⼀一个针对 iPad(加上~ipad 后缀)(要在iPad版本上重新创建视图和重新连接)。

Page 7: 13 UIPopoverController and Modal View Controller

背景颜⾊色•现在我们先不关⼼心 DetailViewController 视图的显⽰示。我们先来处理⼀一下 iPhone 下的纯⽩白背景

•如果是 iPad 的话,我们把背景⾊色设成 groupTableViewBackgroundColor 颜⾊色;如果是 iPhone 的话,给它设定⼀一个和 ItemsViewController接近的颜⾊色

Page 8: 13 UIPopoverController and Modal View Controller

确定 device family

•⾸首先我们要能够判断设备类型•使⽤用 UIDevice 类的类⽅方法 currentDevice 可以得到当前设备,然后通过检查它的 userInterfaceIdiom 属性判断是何种设备。⺫⽬目前有两个可能的值:• UIUserInterfaceIdiomPad - iPad

• UIUserInterfaceIdiomPhone - iPhone 或 iPod touch

Page 9: 13 UIPopoverController and Modal View Controller

userInterfaceIdiom:

•在 DetailViewController.m 中修改 viewDidLoad:

•我们在后⾯面会经常⽤用到这种判断- (void)viewDidLoad{ [super viewDidLoad];// [[self view] setBackgroundColor:[UIColor groupTableViewBackgroundColor]]; UIColor *clr = nil; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { clr = [UIColor groupTableViewBackgroundColor]; } else { clr = [UIColor colorWithRed:0.875 green:0.88 blue:0.91 alpha:1]; } [[self view] setBackgroundColor:clr];}

Page 10: 13 UIPopoverController and Modal View Controller

⾃自动翻转设置•我们要让应⽤用在 iPad 上⽀支持所有⽅方向的翻转,在

iPhone 上只⽀支持 Portrait

•在 ItemsViewController.m 和 DetailViewController.m 中都增加下⾯面的⽅方法

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation{ if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { return YES; } else { return (toInterfaceOrientation == UIInterfaceOrientationPortrait); }}

构建并运⾏行可以看到在 iPad 上视图可以进⾏行翻转

Page 11: 13 UIPopoverController and Modal View Controller

UIPopoverController

Page 12: 13 UIPopoverController and Modal View Controller

•现在 Homepwner 已经可以在 iPad 上运⾏行了,我们可以充分利⽤用 iPad 特有的⽅方法来呈现 view controller

•⾸首先我们来看⼀一下 UIPopoverController

•应⽤用程序经常需要呈现⼀一个 view controller 给⽤用户,让⽤用户选择下⼀一步做什么。⽐比如 image picker。

•在 iPhone 和 iPod touch 上,这类 view controller 通常是模态化呈现,占满整个屏幕。

•有更多屏幕空间的 iPad 有另外⼀一种选择:UIPopoverController

Page 13: 13 UIPopoverController and Modal View Controller

• popover controller 在应⽤用程序界⾯面的上⾯面浮动显⽰示另⼀一个 view controller 的 view,显⽰示在⼀一个边框窗⼝口中。

•当我们⽣生成⼀一个 UIPopoverController 时,我们把这另⼀一个 view controller 设成了 popover controller 的 contentViewController

•我们要实现的是,⽤用户轻击 camera 按钮时,我们在⼀一个 UIPopoverController ⾥里⾯面把 UIImagePickerController 呈现出来

Page 14: 13 UIPopoverController and Modal View Controller

popover controller

Page 15: 13 UIPopoverController and Modal View Controller

popover controller 声明•在 DetailViewController 中增加⼀一个实例变量来持有 popover controller;同时声明 DetailViewController 符合 UIPopoverControllerDelegate

@interface DetailViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate>{ __weak IBOutlet UITextField *nameField; __weak IBOutlet UITextField *serialNumberField;

__weak IBOutlet UILabel *dateLabel; __weak IBOutlet UITextField *valueField;

__weak IBOutlet UIImageView *imageView; UIPopoverController *imagePickerPopover;}

Page 16: 13 UIPopoverController and Modal View Controller

创建,设置和呈现 popover

•如果是 iPad 的话,获取图⽚片时⽤用 popover controller;在 DetailViewController.m 中,在 takePicture: 末尾增加下列代码

[imagePicker setDelegate:self]; // 把 image picker 放到屏幕上// [self presentViewController:imagePicker animated:YES completion:nil]; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { // 创建⼀一个新的将要显⽰示 imagePicker 的 popover control imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:imagePicker]; [imagePickerPopover setDelegate:self]; [imagePickerPopover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; } else { [self presentViewController:imagePicker animated:YES completion:nil]; }}

Page 17: 13 UIPopoverController and Modal View Controller

释放 popover

•构建并在 iPad 模拟器中运⾏行,导航到 DetailViewController 然后点击 camera 按钮,pop over 会出现并且显⽰示 image picker。选择⼀一个图⽚片,会出现在 DetailViewController 的 view 上。

•我们可以点击屏幕上的任何位置来释放这个 popover controller。当 popover 被以这种⽅方式释放时,它发送⼀一个 popoverControllerDidDismissPopover: 消息给它的 delegate

Page 18: 13 UIPopoverController and Modal View Controller

popoverControllerDidDismissPopover:

•在 DetailViewController.m 中实现这个⽅方法

•注意这⾥里我们把 imagePickerPopover 设成 nil 来销毁它,我们每次点击 camera 按钮时都会⽣生成⼀一个新的

- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController{ NSLog(@"释放 popover"); imagePickerPopover = nil;}

Page 19: 13 UIPopoverController and Modal View Controller

选完图⽚片后释放 popover

•在DetailViewController.m 中 imagePickerController:didFinishPickingMediaWithInfo: 末尾增加代码来释放 popover

[imageView setImage:image]; // 把 image picker 从屏幕上移⾛走,必须调⽤用这个 dismiss ⽅方法// [self dismissViewControllerAnimated:YES completion:nil]; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { [self dismissViewControllerAnimated:YES completion:nil]; } else { [imagePickerPopover dismissPopoverAnimated:YES]; imagePickerPopover = nil; }}

•因为显式发送 dismissPopoverAnimated: 消息释放时,不会发送 popoverControllerDidDismissPopover: 给它的 delegate,所有这⾥里要设置 imagePickerPopover 为 nil

Page 20: 13 UIPopoverController and Modal View Controller

销毁不可⻅见的 popover controller

•还有⼀一个⼩小 bug 要处理,UIPopoverController 可⻅见的情况下,再次点击 camera 按钮,应⽤用会崩溃

•原因是点击 camera 按钮,在 takePicture: 中imagePickerPopover 被设成了新的 UIPopoverController,这时屏幕上的 UIPopoverController 就被销毁。

•已经销毁的对象还是可⻅见的,就出现异常了。我们要确保销毁的是不可⻅见的 UIPopoverController

Page 21: 13 UIPopoverController and Modal View Controller

已有,先释放•在 DetailViewController.m 中,takePicker: 顶部增加下⾯面的代码,增加对 imagePickerPopover 是否可⻅见的判断

•这就实现了点击 camera,如果当前有显⽰示 popover,先释放

- (IBAction)takePicture:(id)sender { // 避免多次点击camera按钮引起异常 if ([imagePickerPopover isPopoverVisible]) { [imagePickerPopover dismissPopoverAnimated:YES]; imagePickerPopover = nil; return; } UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

Page 22: 13 UIPopoverController and Modal View Controller

更多关于模态化 View Controller

Page 23: 13 UIPopoverController and Modal View Controller

•在这个部分,我们更新 Homepwner,让它在⽤用户新建⼀一个 BNRItem 时模态化的呈现 DetailViewController

•当⽤用户选择⼀一个已经存在的 BNRItem 时,我们和之前⼀一样把 DetailViewController 压⼊入 UINavigationController 的堆栈

Page 24: 13 UIPopoverController and Modal View Controller

新建⼀一个 BNRItem

Page 25: 13 UIPopoverController and Modal View Controller

双重⽤用法•要实现 DetailViewController 的双重⽤用法(new 或

edit),我们要给它⼀一个名为 initForNewItem: 的新的 designated initializer

•在这个 initializer 中检查这个实例是被⽤用来⽣生成⼀一个新的 BNRItem 还是⽤用来显⽰示⼀一个已经存在的,然后对应的来设置⽤用户界⾯面

•⾸首先在 DetailViewController.h 中声明这个 initializer

- (id)initForNewItem:(BOOL)isNew;

@property (nonatomic, strong) BNRItem *item;

Page 26: 13 UIPopoverController and Modal View Controller

Done 和 Cancel

•如果 DetailViewController 被⽤用来⽣生成⼀一个新的 BNRItem,我们希望在它的 navigation item 上显⽰示⼀一个 Done 按钮和⼀一个 Cancel 按钮

•在 DetailViewController.m 中实现这个⽅方法

Page 27: 13 UIPopoverController and Modal View Controller

实现 initForNewItem:

•如果是新建的话,设置左右按钮

- (id)initForNewItem:(BOOL)isNew{ self = [super initWithNibName:@"DetailViewController" bundle:nil]; if (self) { if (isNew) { UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(save:)]; [[self navigationItem] setRightBarButtonItem:doneItem]; UIBarButtonItem *cancelItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel:)]; [[self navigationItem] setLeftBarButtonItem:cancelItem]; } } return self;}

Page 28: 13 UIPopoverController and Modal View Controller

重写超类 designated initializer

•之前我们更改 designated initializer 的话,会重写超类的 initializer 来调⽤用新的。这⾥里我们通过抛出⼀一个异常来使对超类 designated initializer 的调⽤用⾮非法

•在 DetailViewController.m 中,重写 UIViewController 的 designated initializer

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{ @throw [NSException exceptionWithName:@"Wrong initializer" reason:@"Use initForNewItem" userInfo:nil]; return nil;}

•NSException。异常时,name 和 reason 会在控制台显⽰示

Page 29: 13 UIPopoverController and Modal View Controller

确认异常•⺫⽬目前在 ItemsViewController 的

tableView:didSelectRowAtIndexPath: ⽅方法中调⽤用 initWithNibName:bundle: ⽅方法(对 init ⽅方法的调⽤用最终会调⽤用 initWithNibName:bundle :⽅方法)

•构建并运⾏行,在表格中选择⼀一⾏行的结果是 “Wrong initializer”异常被抛出,程序挂起,可以在控制台中看到⼀一个异常(name 和 reason)

Page 30: 13 UIPopoverController and Modal View Controller

使⽤用新的 initializer

•为了消除这个异常,我们在 ItemsViewController.m 中更新 tableView:didSelectRowAtIndexPath: 以使⽤用新的 initializer

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{// DetailViewController *detailViewController = [[DetailViewController alloc] init]; DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:NO]; NSArray *items = [[BNRItemStore defaultStore] allItems];

Page 31: 13 UIPopoverController and Modal View Controller

•现在我们已经能让新的 initializer ⼯工作了,下⾯面更改⼀一下⽤用户增加⼀一个新的 item 时我们的操作

•在 ItemsViewController.m 中,编辑 addNewItem: 来在 UINavigationController 中创建⼀一个 DetailViewController 的实例,并且把这个 navigation controller 模态化的呈现

Page 32: 13 UIPopoverController and Modal View Controller

修改 ItemsViewController.m 中addNewItem

•构建并运⾏行,DetailViewController 从底部滑出

- (IBAction)addNewItem:(id)sender{ BNRItem *newItem = [[BNRItemStore defaultStore] createItem]; // int lastRow = [[[BNRItemStore defaultStore] allItems] indexOfObject:newItem];// // NSIndexPath *ip = [NSIndexPath indexPathForItem:lastRow inSection:0];// // // 把这个新⾏行插⼊入 table// [[self tableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationTop]; DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:YES]; [detailViewController setItem:newItem]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController]; [self presentViewController:navController animated:YES completion:nil];}

Page 33: 13 UIPopoverController and Modal View Controller

模态化 view controllers 的释放

Page 34: 13 UIPopoverController and Modal View Controller

•要释放(dismiss)⼀一个模态化呈现的 view controller,必须给呈现它的 view controller 发送 dismissViewControllerAnimated:completion: 消息

•我们在之前的 DetailViewController 中,当 UIImagePickerController 完成⼯工作并告诉 DetailViewController 以后, DetailViewController 就把它释放了

Page 35: 13 UIPopoverController and Modal View Controller

•现在的情况稍有不同。当⼀一个新的 item 被⽣生成时,ItemsViewController 模态化的呈现这个 DetailViewController。

•这个 DetailViewController 在它的 navigationItem 上有两个按钮:Cancel 和 Done,按钮按下时 DetailViewController 将被释放

Page 36: 13 UIPopoverController and Modal View Controller

•问题是,这些按钮的 action message 是发给 DetailViewController 的,DetailViewController 需要⼀一种⽅方法来告诉呈现它的并且负责释放它的 ItemViewController,它已经完⼯工可以被释放了

Page 37: 13 UIPopoverController and Modal View Controller

•幸运的是,每个 UIViewController 都有⼀一个 presentingViewController 属性,这个属性指向呈现它的 view controller

•DetailViewController 将会获取⼀一个指向它的 presentingViewController 的指针,并把 dismissViewControllerAnimated:completion: 消息发送给它

presentingViewController 属性

Page 38: 13 UIPopoverController and Modal View Controller

实现 save action ⽅方法•在 DetailViewController.m 中实现为 Done 按钮实现它的 save action ⽅方法

- (void)save:(id)sender{ [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];}

Page 39: 13 UIPopoverController and Modal View Controller

Cancel -> 删除新建的 item

• Cancel 按钮需要多做⼀一点⼯工作。

•⽤用户点击 ItemViewController 的按钮添加⼀一个新的 item 到列表,就创建了⼀一个新的 BNRItem 实例,添加到 store,然后 DetailViewController 才滑动出来供我们编辑

•如果⽤用户取消了这个 item 的⽣生成,那么这个 BNRItem 就需要从 store 中删除

•所以我们需要在 Cancel 结束后多做⼀一些⼯工作

Page 40: 13 UIPopoverController and Modal View Controller

Cancel 的实现•⾸首先要在 DetailViewController.m 中导⼊入

BNRItemStore 的头⽂文件

#import "DetailViewController.h"#import "BNRItem.h"#import "BNRImageStore.h"#import "BNRItemStore.h"

- (void)cancel:(id)sender{ [[BNRItemStore defaultStore] removeItem:item]; [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];}

•构建并运⾏行,新建然后cancel,不会有内容添加到 table view;新建,然后 Done,DetailViewController 将滑出屏幕

Page 41: 13 UIPopoverController and Modal View Controller

action message 的验证•注意 cancel: 和 save: ⽅方法没有在任何地⽅方做声明,这并没有什么问题

•声明⼀一个⽅方法是为了让编译器知道这个⽅方法的存在,在设置 UIBarButtonItem 和 UIControl 的 action 时,编译器不会验证 action message,因为此时并没有调⽤用。消息是在运⾏行时实际被发送时才被验证

•如果这个⽅方法被定义了,将会运⾏行良好;否则就会得到⼀一个 unrecognized selector exception

Page 42: 13 UIPopoverController and Modal View Controller

真正的 presentingViewController

•UINavigationController

Page 43: 13 UIPopoverController and Modal View Controller

Modal view controller 的样式

Page 44: 13 UIPopoverController and Modal View Controller

•在 iPhone 和 iPod touch上,⼀一个模态化 view controller 会展满整个屏幕,是默认的⽽而且也只能这样

•在 iPad 上,我们有两个附加选项:

• form sheet style

•和 page sheet style

Page 45: 13 UIPopoverController and Modal View Controller

•我们可以通过设置modal view controller 的 modalPresentationStyle 属性为⼀一个预设的常量:

• UIModalPresentationFormSheet

•或 UIModalPresentationPageSheet 来更改这个呈现

Page 46: 13 UIPopoverController and Modal View Controller

form sheet style

• form sheet style 在 iPad 屏幕中间的⼀一个矩形内显⽰示模态化 view controller,并且把呈现它的 view controller 的 view 变暗

Page 47: 13 UIPopoverController and Modal View Controller

page sheet style

•在 portrait 模式下和默认全屏相同

•在 landscape 模式下,保持它的宽度和portrait 模式下相同,并且把贴在它下⾯面的呈现它的 view controller 的左右边变暗

Page 48: 13 UIPopoverController and Modal View Controller

改变 presentation style

•在 ItemsViewController.m 中修改 addNewItem: ⽅方法来变更被呈现的 UINavigationController 的 presentation style

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController]; [navController setModalPresentationStyle:UIModalPresentationFormSheet]; [self presentViewController:navController animated:YES completion:nil];

Page 49: 13 UIPopoverController and Modal View Controller

新的 item 不⻅见了?•再次构建并运⾏行,点击按钮增加⼀一个新的item,

modal view controller 滑⼊入屏幕。然后点击 Done 按钮,table view 重新出来了,但是新的 BNRItem 并没有显⽰示出来!??

Page 50: 13 UIPopoverController and Modal View Controller

•变更 presentation style 前,modal view controller 是全屏显⽰示的,这引起了 ItemsViewController 的 view disappear。

•当 modal view controller 被 dismiss 后,ItemsViewController 被发送 viewWillAppear: 消息,然后我们是在 viewWillAppear: 中重新加载所有新加的数据

Page 51: 13 UIPopoverController and Modal View Controller

table view 重新加载数据•当使⽤用新的 presentation style 时,

ItemsViewController 的 view 在它呈现 view controller 的时候并没有消失(只是颜⾊色变暗了)。

•因⽽而在 modal view controller 被 dismissed 的时候没有被发送重新出现的消息,因此也没有机会重新加载数据。

Page 52: 13 UIPopoverController and Modal View Controller

• ItemsViewController 重新加载它的 table view 的代码很简单:

•类似:[[self tableview] reloadData]

•但是我们必须找到⼀一个机会来重新加载这些数据

Page 53: 13 UIPopoverController and Modal View Controller

•我们需要做的是打包上⾯面的代码,然后恰好在 modal view controller 被 dismissed 的时候让它执⾏行

•我们可以使⽤用 dismissViewControllerAnimated:completion: 中⼀一个内置的机制来完成这个

Page 54: 13 UIPopoverController and Modal View Controller

Completion blocks

Page 55: 13 UIPopoverController and Modal View Controller

•我们可以把重新加载 table view 的代码放⼊入⼀一个 block,然后传给 dismissViewControllerAnimated:completion: , 然后代码就正好在 modal view controller 被 dismissed 时候执⾏行

•在 DetailViewController.h 中,增加⼀一个指向⼀一个 block 的属性,在 .m 中 synthesize

@property (nonatomic, copy) void (^dismissBlock)(void);

@implementation DetailViewController

@synthesize item;@synthesize dismissBlock;

Page 56: 13 UIPopoverController and Modal View Controller

传递 block•我们不能在 DetailViewController ⾃自⾝身中创建这个

block,⽽而只能在 ItemsViewController 中创建,只有 ItemsViewController 才知道它的 tableView

•在 ItemsViewController.m 中的 addNewItem: ⽅方法中,⽣生成⼀一个重新加载 ItemsViewController 的表格的 block,并把它传给 DetailViewController

- (IBAction)addNewItem:(id)sender{ BNRItem *newItem = [[BNRItemStore defaultStore] createItem]; DetailViewController *detailViewController = [[DetailViewController alloc] initForNewItem:YES]; [detailViewController setItem:newItem]; [detailViewController setDismissBlock:^{ [[self tableView] reloadData]; }]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];

Page 57: 13 UIPopoverController and Modal View Controller

•这时当⽤用户再点击按钮添加⼀一个新的 item 时,⼀一个重新加载 ItemsViewController 的表格的 block 会被创建,并被设成 DetailViewController 的 dismissBlock。

•DetailViewController 将会持有这个block 直到 DetailViewController 需要被释放

•在被释放时,DetailViewController 将把这个 block 传给 dismissViewControllerAnimated:completion:

Page 58: 13 UIPopoverController and Modal View Controller

•在 DetailViewController.m 中修改 save: 和 cancel: 的实现,使⽤用 dismissBlock 作为⼀一个参数发送 dismissViewControllerAnimated:completion: 消息

•再构建并运⾏行,新增加的 BNRItem 就会出现在表格中了

- (void)cancel:(id)sender{ [[BNRItemStore defaultStore] removeItem:item]; // [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil]; [[self presentingViewController] dismissViewControllerAnimated:YES completion:dismissBlock];}- (void)save:(id)sender{// [[self presentingViewController] dismissViewControllerAnimated:YES completion:nil]; [[self presentingViewController] dismissViewControllerAnimated:YES completion:dismissBlock];}

Page 59: 13 UIPopoverController and Modal View Controller

Modal view controller 的转换

Page 60: 13 UIPopoverController and Modal View Controller

•最后我们看⼀一下 modal view controller 的 transitions。

•除了可以更改 modal view controller 的 presentation style 之外,我们也可以更改把它放置到屏幕上时的动画效果。

Page 61: 13 UIPopoverController and Modal View Controller

•使⽤用 modalTransitonStyle 属性,可以设置⼀一个预定义的常量。

•默认是将从屏幕底部滑出到屏幕•在 ItemsViewController.m 中更新 addItmName: ⽅方法使⽤用⼀一个不同的 transition(横向翻动)

[navController setModalPresentationStyle:UIModalPresentationFormSheet]; [navController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal]; [self presentViewController:navController animated:YES completion:nil];