Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2697298
  • 博文数量: 877
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 5921
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-05 12:25
个人简介

技术的乐趣在于分享,欢迎多多交流,多多沟通。

文章分类

全部博文(877)

文章存档

2021年(2)

2016年(20)

2015年(471)

2014年(358)

2013年(26)

分类: iOS平台

2015-08-20 13:30:06

Storyboard使用心得
http://blog.csdn.net/quanqinyang/article/details/17137759

最近接触IOS7新特性,之前项目都是使用xib,没有使用过storyboard,今天就研究下。首先,说下storyboard优缺点,优点a). 流程结构清晰b). 有内置的segue支持c). 方便的实例化ViewController缺点a). 所有的ViewController都在同一个Storyboard里编辑,随着场景的增加,i). XCode打开Storyboard的速度会越来越慢。ii). 所有的ViewController会并列在编辑器左侧,不方便编辑。 b). 无法单独调整每个整场景的生命周期,所有的场景生命周期由storyboard控制,一旦加载了一个场景,除非storyboard卸载,否则无法。(一个超级大bug)。xib的可定制性要大于storyboard,storyboard适用于快速开发小型项目,团队开发感觉不太适合。

现在,说下storyboard的使用,是IOS5的新特性。在xcode5中新建一个Single View Application(也可以新建一全Empty Application) ,如图所示:
AppDelegate.m文件中也会有发现变化,

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

   returnYES;

}


这跟以前不一样了!

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions


{

   self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];

   // Override point for customization after application launch.

   self.viewController = [[[ViewController alloc] initWithNibName:@"ViewController" bundle:nil] autorelease];

   self.window.rootViewController =self.viewController;

    [self.window makeKeyAndVisible];

   returnYES;

}

这是因为程序会自动加载Main Storyboard。如果你把上面的Main Storyboard项清空了,那我们的Storyboard.storyboard就是一个孤立的文件了,你必须手动加载它,所以上面的代码也得改一改,如下:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

   self.window = [[UIWindowalloc]initWithFrame:[[UIScreen mainScreen]bounds]];

   UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];

   self.window.rootViewController = [storyboard instantiateInitialViewController];

    [self.window  makeKeyAndVisible];

   returnYES;

}

接下来打开Main.storyboard文件,默认显示有一个ViewController。现在我们加入一个Navigation Controller,可以直接拖放一个Navigation Controller进来,把原来的ViewController删掉,也可以点击Editor ->Embed In ->Navigation Controller创建,这种方法不用删掉原来的ViewController。如图:

可以看到出现了两个视图控制器,这是因为Navigation Controller需要一个rootViewController。注意我标注的两个小箭头,左边的代表这是一个“初始视图控制器”,右边的代表两个视图控制器之间的关系。选中视图控制器可查看属性。如图:


取消勾选“Is Initial View Controller”后指向视图控制器的箭头也就消失了。一个Storyboard里只能有一个“初始视图控制器”。如图:



在根控制器中添加一个button,然后继续拖拽一个UITabbarController,接着要做的就是把View Controller和UITabbarController关联起来,有两种方法可以实现,第一种:我们可以直接在Storyboard中完成,按住ctrl从button连接到TabbarController,松开并选择push,这样我们就创建了一个segue(UISotryboardSegue)。如图:


第二种:用代码来实现。(记得把上一步中push类型的segue删除)创建类ViewController中button的点击事件的方法,把UITabbarController的Storyboard Id设置成“second”(4.4版本是Identifier为“second”),效果图如下:


代码如下:

- (IBAction)onClick:(id)sender

{

    UIStoryboard *board=[UIStoryboardstoryboardWithName:@"Main"bundle:nil];

   UITabBarController *nextViewController =[boardinstantiateViewControllerWithIdentifier:@"second"];

    [self.navigationControllerpushViewController:nextViewControlleranimated:YES];

}这样就完成了跳转。

下面将完成另一个目标:手动触发一个segue(Storyboard里无法创建一个通过touch来触发的segue)。拖拽一个UIViewController,把基类设置成"FourthViewController",把TabbarController的第一个分支的ViewController的基类设置成"ThirdViewController",然后按住ctrl从TabbarController的第一个分支连接到新的viewController,同样选择push,把新创建的segue的Identifier设置为"fourth"。在此之前应当创建ThirdViewController和FourthViewController两个类文件。在ThirdViewController类中添加如下方法:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    [selfperformSegueWithIdentifier:@"fourth"sender:nil];

}

在这里也出现了一个小问题,把“fourth”写成了“fourh”,于是就崩掉了,出现了“Receiver has no segue with identifier 'fourh'”提示,经过分析是自己写错了单词,以后大家多注意,可以用CV方式来避免这种问题。

这样就完成 了。效果图如下:


代码下载地址:


页面切换方法:

xib时:

1 显示模态页面

  调用UIViewController的presentModalViewController方法以模态方式显示页面——

- (void)presentModalViewController:(UIViewController *)modalViewController animated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0);

使用这种方式进行切换时,新页面不会继承之前页面中的控件,而是只显示自身界面。

当需要从模态页面中返回时,可调用dismissModalViewControllerAnimated方法——

- (void)dismissModalViewControllerAnimated:(BOOL)animated NS_DEPRECATED_IOS(2_0, 6_0);

2 push到下级页面


当使用导航控制器(UINavigationController)时,可以调用它的pushViewController来转到下级页面——

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated; 

使用这种方式进行切换时,下级页面会继承之前页面中的控件,如顶部的导航条等。
下级页面的导航条的左侧默认会出现返回按钮。如果想手动返回的话,可以调用UINavigationController的popViewControllerAnimated等方法——

- (UIViewController *)popViewControllerAnimated:(BOOL)animated;
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; 
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated; 

Storyboard时:


1 从Storyboard界面

最简单的办法是——在按钮上拖曳鼠标右键到新页面,创建连线(Segue)。


另外一种是:创建一个从ViewController到新页面的Segue,并对该Segue的Identifier进行命名。然后写代码进行切换,调用UIViewController的performSegueWithIdentifier方法进行切换——

- (void)performSegueWithIdentifier:(NSString *)identifier sender:(id)sender NS_AVAILABLE_IOS(5_0);
事例:
[self performSegueWithIdentifier:@"fourth" sender:nil];

2.从纯代码界面

- (id)instantiateViewControllerWithIdentifier:(NSString *)identifier;
事例:
 FourthViewController *fourthVC = [self.storyboard instantiateViewControllerWithIdentifier:@"FourthViewController"];
		

    fourthVC.modalTransitionStyle = UIModalTransitionStyleCoverVertical;

    [self presentViewController:fourthVC animated:YES completion:nil];

performSegueWithIdentifier和instantiateViewControllerWithIdentifier区别
performSegueWithIdentifier方法是基于导航的,在下个页面不需要写返回方法, 
instantiateViewControllerWithIdentifier方法在返回上个页面时需要写 
dismissModalViewControllerAnimated方法。

segue页面间传递数据:
  1. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender  

多个Segue每次动作都会执行这个方法:

在每个ViewController中设置 Storyboard ID,判断segue的标识符即可,如:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

{

if ([[segue identifier] isEqualToString:@"XXXXXX"])

{

}

}



参考:

阅读(355) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~