iOS应用开发视频教程笔记iPad Apps

iOS应用开发视频教程笔记iPad Apps,第1张

概述这节课的主要内容包括iPad、Split Views、Popovers及做一个universal的应用并在两种设备上运行。 UIToolbar 通常在屏幕的顶部或底部,长得像钢筋一样。一个工具栏,是一个UIBarButtonItems的集合。UIBarButtonItems不是按钮,有点像是简化过的按钮。UINavigationController有一个在底部的工具栏,可以通过在xcode里ins

这节课的主要内容包括iPad、Split VIEws、Popovers及做一个universal的应用并在两种设备上运行。

UIToolbar

通常在屏幕的顶部或底部,长得像钢筋一样。一个工具栏,是一个UIbarbuttonItems的集合。UIbarbuttonItems不是按钮,有点像是简化过的按钮。UINavigationController有一个在底部的工具栏,可以通过在xcode里inspect Navigation Controller中的Shows Toolbar小开关打开,但工具栏上的按钮和Navigation Controller本身没有任何关系,它只和当时显示的VIEwController有关。

UIbarbuttonItems

是使UIToolbar真正工作的东西,他们有target action,就像一个按钮。有两个特殊的UIbarbuttonItems,Fixed和Flexible space,这些都是用来安排你UIToolbar按钮的显示方式。创建一个UIbarbuttonItems的方式是alloc/init,它可以采用文字或图像,或者可以用另一种叫做initWithbarbuttonSystemItem的初始化方法,然后你给它在枚举类型中指定一个。

要创建一个工具栏非常简单,只需将其拖动到你的VIEwController,通常会连到一个outlet,然后只需从xcode中拖个UIbarbuttons到它里面,或者在代码中设置个数组,工具栏对象有个物品数组。

UISplitVIEwController

创建一个UISplitVIEwController的方法是在xcode里将它托出来,只能拖动Split VIEw到一个ipad类型的storyboard。Split VIEw通常只是一个基本元素,它填满整个屏幕,不可能把Split VIEw放到其他什么的内部,一般情况下是提供给整个app的。Split VIEw有两个VIEwControllers,一个左侧一个右侧,左侧叫Master,右侧叫Detail。SplitVIEwController有一个property叫做VIEwControllers,它是一个数组,这个数组有两个元素,左侧和右侧,左侧是元素0,右侧是元素1,可以在代码中设置你的两个VIEwController(通常得同时设置),可以在xcode中设置这两个东西,可以control拖动到左侧来设置左侧或拖动到右侧来设置右侧,然后它要改变就用segue。

@property (nonatomic,copy) NSArray *vIEwControllers;

此API不希望你传递含有这两个VIEwController的可变数组,然后期待如果你改变了一个,它会以某种方式更新Split VIEw。所以这里说的是我要复制你给我的东西,而且我要使用它。所以如果你要改变它,你得再给我一次。就是不想让你传递可变数组,以防止你改变了它导致发生意外。

Split VIEw不能没有delegate,如果没有设置delegate,那么当Split VIEw进入Portrait模式的时候左侧就会消失,你应该在角落里放一个小按钮,使用户可以点击它来让左侧出现在popover里。这是Split VIEw的工作原理。如果不实现delegate就没办法放上那个按钮,就无法在portrait模式下调出左侧。通常情况下,你要在VIEwController的vIEwDIDLoad或awakeFromNib方法里设置此delegate。所以Split VIEw的delegate最主要的任务就是处理旋转,delegate是管理左侧的。

- (BOol)splitVIEwController:(UISplitVIEwController *)sender   shouldHIDeVIEwController:(UIVIEwController *)master              inorIEntation:(UIInterfaceOrIEntation)orIEntation{     return YES; // always hIDe it}

这个delegate方法是被发送到你的delegate询问在特定方向下你想要左侧做什么,因此它把自己传递给你,还有左侧,它会问在这个方向你想要我对左侧做什么。要隐藏就返回YES,要保留在屏幕上就返回NO。

return UIInterfaceOrIEntationIsPortrait(orIEntation);}

这是如果不实现delegate其余的方法会出现的问题,因为portrait会隐藏左侧,但你没有放那个小按钮,系统不会帮你做这一步。它会给你按钮,但你得把它放到屏幕上。因此,其余的delegate方法就是要把按钮放上去。其中有两个非常重要,一个用来把按钮放上去,一个用来把按钮拿掉。例如旋转回Landscape:

- (voID)splitVIEwController:(UISplitVIEwController *)sender     willHIDeVIEwController:(UIVIEwController *)master          withbarbuttonItem:(UIbarbuttonItem *)barbuttonItem       forPopoverController:(UIPopoverController *)popover{     barbuttonItem.Title = @“Master”;  use a better word than “Master”!      setSplitVIEwbarbuttonItem: must put the bar button somewhere on screen      probably in a UIToolbar or a UINavigationbar     [detailVIEwController setSplitVIEwbarbuttonItem:barbuttonItem];}

这是用来隐藏左侧的,它给你一个barbutton,就是第三个参数,它说把这个barbutton放到屏幕上,因为我将要隐藏左侧的VIEwController。当这个barbutton被按下,它会自动显示左侧,但是必须把barbutton放到某处。

当你想要旋转回Landscape,并把左侧放回到屏幕上,它会向你发送此消息:

voID)splitVIEwController:(UISplitVIEwController *)sender willShowVIEwController:(UIVIEwController *)master invalIDatingbarbuttonItem:(UIbarbuttonItem *)barbuttonItem{ removeSplitVIEwbarbuttonItem: must remove the bar button from its toolbar [detailVIEwController removeSplitVIEwbarbuttonItem:nil];}

这就是把按钮从工具栏里移除,因为不想左侧显示时,还有这个按钮。

有很多办法可以用来实现SplitVIEw delegate,这取决于在两侧使用的是什么VIEwController。何时该设置delegate:一、你得决定谁是delegate,是左侧的Master还是右侧detail?此外你得去考虑可重用性,两者之一可能是通用的,所以不能在那上面实现SplitVIEw delegate,它是一个通用的可重复使用的vIEw。这有个例子,在Detail一侧总是把按钮放上去,那么按钮就总是在Detail一侧。

voID)setSplitVIEwbarbuttonItem:(UIbarbuttonItem *)barbuttonItem{ UIToolbar *toolbar = [self toolbar]; might be outlet or calculated NSMutableArray *toolbaritems = [toolbar.items mutablecopy]; if (_splitVIEwbarbuttonItem) [toolbaritems removeObject:_splitVIEwbarbuttonItem]; put the bar button on the left of our existing toolbar if (barbuttonItem) [toolbaritems insertObject:barbuttonItem atIndex:0]; toolbar.items = toolbaritems; _splitVIEwbarbuttonItem = barbuttonItem;}

这个方法会把barbuttonItem插入到工具栏的最左侧,不管工具栏里的其他东西它都会被插在左侧。

通常,点击Master里的东西,Detail显示你点击的东西的详细信息。那么当Master改变时,Detail是怎么更新的?有两个选择,一是简单的target action,在左侧的Master VIEw你已经有了一些按钮或什么,当被点击它会发送target action消息给你的Master Controller。当它想更新Detail,它只要发一个消息到Detail。它是如何从Master得到Detail的?例如Master VIEw Controller里一个target action消息叫doit:

- (IBAction)doit{     ID detailVIEwController = [[self.splitVIEwController vIEwControllers] lastObject];     [detailVIEwController setSomeProperty:...];}

二是也可以segue,在SplitVIEwController里只有一种segue能用,它被称为replace segue,这是因为它会替换Master或Detail。使用replace segue有个要警告的地方:当你替换Detail VIEw的时候,如果工具栏里有SplitVIEw barbutton,该工具栏也被替换,因为整个vIEw都会被替换,所以你得把SplitVIEw barbutton转移出来,得把它转移到新的delegate生成的popover上,通常在准备segue的时候去完成做这些。所以如果你要准备segue,你需要问detail关于它的barbutton,你设置barbutton,然后让segue发生。

Popover

就是漂浮选单,它只是一个NSObject,它控制VIEwController,它的工作基本上就是通过contentVIEwController绘制它的VIEwController。通常Popover发生内容,是因为你control拖动它,并有一个segue。Popover segue做的是,你control拖动它到VIEwController,它会把VIEwController放到Popover里,不管是从按钮或什么拖动,那就是Popover的指向。如果你在代码中做Popover,或使用了storyboard,在storyboard的方法instantiateVIEwControllerWithIDentifIEr会给你一个storyboard外部的VIEwController。如果得到一个VIEwController,然后发消息给UIPopoverController,进行alloc/init就有了PopoverController,你向其发送这两个消息之一,使其出现在屏幕上。

- (voID)presentPopoverFromrect:(CGRect)aRect or                        inVIEw:(UIVIEw *)vIEw      permittedArrowDirections:(UIPopoverArrowDirection)direction                      animated:(BOol)flag;
voID)presentPopoverFrombarbuttonItem:(UIbarbuttonItem *)barbuttonItem permittedArrowDirections:(UIPopoverArrowDirection)direction animated:(BOol)flag;

得保持一个strong指针指向你的PopoverController,所有这些显示的东西都不会有strong指针指向你的PopoverController。

消除Popover,把它从屏幕上去掉,通常是用户触发的,有两种方式:一是如果点击了屏幕上除Popover以外的地方,它会关闭Popover;当你点击Popover里的东西,它是怎么消除的呢?答案是调用了dismisspopoverAnimated,但你不能从popover里的VIEwController调用dismisspopoverAnimated。不管把Popover放上来的是哪个对象,这个对象就应该负责消除Popover。

Popover有delegate,实际上它有两个方法,一是问你是否要消除,另一个是告诉你它何时被消除,但这只发生在有人通过点击Popover以外的地方来消除的情况。

设置Popover大小的方式:一最常用的方法是在xcode里设置,选中一个VIEwController并inspect它,通过Popover小开关打开并指定大小;二是通过UIVIEwController中的contentSizeforVIEwInPopover方法;第三种方式是UIPopoverController有个方法可以设置Popover的大小。

Universal Applications

一个通用app就是单一一个应用程序,但可以运行在ipad或iphone上,可以共享VIEwController。调用这个宏UI_USER_INTERFACE_IdioM可以知道在ipad上运行,你问它是UIUserInterfaceIdiomPad还是UIUserInterfaceIdiomPhone,这会告诉你是否在ipad上运行:

BOol iPad = (UI_USER_INTERFACE_IdioM() == UIUserInterfaceIdiomPad);

但这不是最好的办法,询问我是否处在SplitVIEwController里会更好。

Demo

修改上一节的demo,使其成为一个通用app,其中要创建一个ipad的storyboard。

修改spring&structs,如果视图控制器是UIVIEwController类,则需要一个UIVIEwController子类重载shouldautorotatetoInterfaceOrIEntation方法才能进行旋转。创建完UIVIEwController的子类后只要留下shouldautorotatetoInterfaceOrIEntation方法,并使它返回yes。

修改app设置使其成为一个通用app,把原来的MainStoryboard.storyboard改为:iPhone.storyboard,修改iPhone的storyboard:

新建iPad.storyboard,并设置iPad的storyboard。

在iPad.storyboard里拖一个SplitVIEwController进来,删除tableVIEwController,修改右侧控制器的类为HappinessVIEwController,再拖一个VIEw到HappinessVIEwController并把它的类修改为FaceVIEw,要设置outlet和action。在iPhone.storyboard中复制根视图控制器,到iPad.storyboard再粘贴,从导航控制器control拖动到根视图控制器,再把Psychologist VIEw Controller粘贴过来并用segue关联起来:

修改PsychologistVIEwController.m中的代码如下:

- (HappinessVIEwController *)splitVIEwHappinessVIEwController{    ID hvc = [self.splitVIEwController.vIEwControllers lastObject];    if (![hvc isKindOfClass:[HappinessVIEwController class]]) {        hvc = nil;    }    return hvc;}- (voID)setAndShowDiagnosis:(int)diagnosis{    self.diagnosis = diagnosis;    if ([self splitVIEwHappinessVIEwController]) {        [self splitVIEwHappinessVIEwController].happiness = diagnosis;    }else{        [self performSegueWithIDentifIEr:@"ShowDiagnosis" sender:self];    }}

把SplitVIEw delegate放进RotatableVIEwController,让RotatableVIEwController成为SplitVIEw的delegate。RotatableVIEwController的代码如下:

#import <UIKit/UIKit.h>@interface RotatableVIEwController : UIVIEwController<UISplitVIEwControllerDelegate>@end

#import "RotatableVIEwController.h"SplitVIEwbarbuttonItemPresenter.h@implementation RotatableVIEwController- (voID)awakeFromNib{    [super awakeFromNib];    self.splitVIEwController.delegate = self;}- (ID <SplitVIEwbarbuttonItemPresenter>)splitVIEwbarbuttonItemPresenter{    ID detailVC = [self.splitVIEwController.vIEwControllers lastObject];    if (![detailVC conformstoprotocol:@protocol(SplitVIEwbarbuttonItemPresenter)]) {        detailVC = nil;    }    return detailVC;}- (BOol)splitVIEwController:(UISplitVIEwController *)svc   shouldHIDeVIEwController:(UIVIEwController *)vc              inorIEntation:(UIInterfaceOrIEntation)orIEntation{    return [self splitVIEwbarbuttonItemPresenter]? UIInterfaceOrIEntationIsPortrait(orIEntation) : NO;}- (voID)splitVIEwController:(UISplitVIEwController *)svc     willHIDeVIEwController:(UIVIEwController *)aVIEwController          withbarbuttonItem:(UIbarbuttonItem *)barbuttonItem       forPopoverController:(UIPopoverController *)pc{    barbuttonItem.Title = self.Title;    [self splitVIEwbarbuttonItemPresenter].splitVIEwbarbuttonItem = barbuttonItem;}- (voID)splitVIEwController:(UISplitVIEwController *)svc     willShowVIEwController:(UIVIEwController *)aVIEwController  invalIDatingbarbuttonItem:(UIbarbuttonItem *)barbuttonItem{    [self splitVIEwbarbuttonItemPresenter].splitVIEwbarbuttonItem = nil;}- (BOol)shouldautorotatetoInterfaceOrIEntation:(UIInterfaceOrIEntation)interfaceOrIEntation{     Return YES for supported orIEntations    return YES;}@end

创建一个protocol,代码如下:

@protocol SplitVIEwbarbuttonItemPresenter <NSObject>@property (nonatomic,strong) UIbarbuttonItem *splitVIEwbarbuttonItem;

HappinessVIEwController .h文件代码:

#import <UIKit/UIKit.h>@interface HappinessVIEwController : UIVIEwController<SplitVIEwbarbuttonItemPresenter>@property (nonatomic) int happiness; 0 is sad; 100 is very happy

HappinessVIEwController.m实现协议:

HappinessVIEwController.h"FaceVIEw.h@interface HappinessVIEwController() <FaceVIEwDataSource>@property (nonatomic,weak) IBOutlet FaceVIEw *faceVIEw;@property (nonatomic,weak) IBOutlet UIToolbar *toolbar;@end@implementation HappinessVIEwController@synthesize happiness = _happiness;@synthesize faceVIEw = _faceVIEw;@synthesize splitVIEwbarbuttonItem = _splitVIEwbarbuttonItem;@synthesize toolbar = _toolbar;- (voID)setSplitVIEwbarbuttonItem:(UIbarbuttonItem *)splitVIEwbarbuttonItem{ if (_splitVIEwbarbuttonItem != splitVIEwbarbuttonItem) { NSMutableArray *toolbaritems = [self.toolbar.items mutablecopy]; if (_splitVIEwbarbuttonItem) { [toolbaritems removeObject:_splitVIEwbarbuttonItem]; } if (splitVIEwbarbuttonItem) { [toolbaritems insertObject: splitVIEwbarbuttonItem atIndex:0 ]; } self.toolbar.items = toolbaritems; _splitVIEwbarbuttonItem = splitVIEwbarbuttonItem; }}.......

运行结果如下所示:

总结

以上是内存溢出为你收集整理的iOS应用开发视频教程笔记iPad Apps全部内容,希望文章能够帮你解决iOS应用开发视频教程笔记iPad Apps所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1088381.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存