`
啸笑天
  • 浏览: 3465644 次
  • 性别: Icon_minigender_1
  • 来自: China
社区版块
存档分类
最新评论

ios5中UIViewController addChildViewController等新方法

 
阅读更多

ios4还是3,以前基于在vviewcontroller上的切换,基本上就2中方式,导航控制器上的push,或者普通控制器上modal,现在终于多了一个这种玩意儿了。在ios5中,ViewController中新添加了下面几个方法:

addChildViewController: 
removeFromParentViewController 
transitionFromViewController:toViewController:duration:options:animations:completion: 
willMoveToParentViewController: 
didMoveToParentViewController:

下面详细介绍一下addChildViewController,一个ViewController可以添加多个子ViewController,但是这些子ViewControlle要想显示出来,需要把子controller的视图添加到父视图的相应位置r,可以通过transitionFromViewController:toViewController:duration:options:animations:completion:这个方法转换显示的子视图。同时加入相应的动画。下面以一个例子来说明这几个新方法:

下面详细介绍一下上述效果的实现:

  1. 创建项目,changeViewController。
  2. 添加相应的viewController,MainViewController、FirstViewController、SecondViewController、ThirdViewController。

3.把MainViewController添加到window中。

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

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // Override point for customization after application launch. 
    MainViewController *mainViewController=[[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil]; 
    self.window.rootViewController=mainViewController; 
    [self.window makeKeyAndVisible]; 
    return YES; 
}

4.在MainViewController中添加三个按钮,并且连接onClickbutton方法。

5.在MainViewController中添加三个子controller

#pragma mark – View lifecycle

   

- (void)viewDidLoad 

    [super viewDidLoad]; 
    // Do any additional setup after loading the view from its nib. 
    
    FirstViewController *firstViewController=[[FirstViewController alloc] initWithNibName:@"FirstViewController" bundle:nil]; 
    [self addChildViewController:firstViewController]; 
    
    SecondViewController *secondViewController=[[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil]; 
    [self addChildViewController:secondViewController]; 
    
    
    ThirdViewController *thirdViewController=[[ThirdViewController alloc] initWithNibName:@"ThirdViewController" bundle:nil]; 
    [self addChildViewController:thirdViewController]; 
    
    [contentView addSubview:thirdViewController.view]; 
    
    currentViewController=thirdViewController; 
    
}

其中要把其中的一个子controller的view添加到根视图中,这样才能显示出相应的视图。

6.点击按钮,切换视图。

-(IBAction)onClickbutton:(id)sender 

    FirstViewController *firstViewController=[self.childViewControllers objectAtIndex:0]; 
    ThirdViewController *thirdViewController=[self.childViewControllers objectAtIndex:2]; 
    SecondViewController *secondViewController=[self.childViewControllers objectAtIndex:1]; 
    if ((currentViewController==firstViewController&&[sender tag]==1)||(currentViewController==secondViewController&&[sender tag]==2) ||(currentViewController==thirdViewController&&[sender tag]==3) ) { 
        return; 
    } 
    UIViewController *oldViewController=currentViewController; 
    switch ([sender tag]) { 
        case 1: 
        { 
            NSLog(@"留言及回复"); 
            [self transitionFromViewController:currentViewController toViewController:firstViewController duration:4 options:UIViewAnimationOptionTransitionFlipFromLeft animations:^{ 
            }  completion:^(BOOL finished) { 
                if (finished) { 
                    currentViewController=firstViewController; 
                }else{ 
                    currentViewController=oldViewController; 
                } 
            }]; 

            break; 
        case 2: 
        { 
            NSLog(@"生日提醒"); 
            [self transitionFromViewController:currentViewController toViewController:secondViewController duration:1 options:UIViewAnimationOptionTransitionFlipFromTop animations:^{ 
                
            }  completion:^(BOOL finished) { 
                if (finished) { 
                  currentViewController=secondViewController; 
                }else{ 
                    currentViewController=oldViewController; 
                } 
            }]; 
        } 
            break; 
        case 3: 
        { 
            NSLog(@"好友申请"); 
            [self transitionFromViewController:currentViewController toViewController:thirdViewController duration:1 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{ 
                
            }  completion:^(BOOL finished) { 
                if (finished) { 
                     currentViewController=thirdViewController; 
                }else{ 
                    currentViewController=oldViewController; 
                } 
            }]; 
        } 
            break; 
        default: 
            break; 
    } 
}

其中我把按钮设置成不同的tag了。

这时候点击按钮,就可以切换子视图了。

可以看到,这些view在没有使用时,是不会被load的,并且当有Memory Warning时,当前没有显示的view自动被unload掉了。

这样写的好处:

  • 多个UIViewController之间切换可以添加动画
  • 当内存警告的时候,可以把当前不是激活状态的ViewController内存释放。所以新的方法确实能有效地节省内存,也能方便地处理内存不足时的资源回收
  • 可以把代码更好分开

thx google!

分享到:
评论
2 楼 啸笑天 2015-03-20  
@implementation UIViewController (NLFrostedViewController)
- (void)nl_displayController:(UIViewController *)controller frame:(CGRect)frame
{
    [self addChildViewController:controller];
    controller.view.frame = frame;
    [self.view addSubview:controller.view];
    [controller didMoveToParentViewController:self];
}

- (void)nl_hideController:(UIViewController *)controller
{
    [controller willMoveToParentViewController:nil];
    [controller.view removeFromSuperview];
    [controller removeFromParentViewController];
}
1 楼 啸笑天 2015-03-20  
iOS 5.0 后UIViewController新增:willMoveToParentViewController和didMoveToParentViewController



在iOS 5.0以前,我们在一个UIViewController中这样组织相关的UIView



在以前,一个UIViewController的View可能有很多小的子view。这些子view很多时候被盖在最后,我们在最外层ViewController的viewDidLoad方法中,用addSubview增加了大量的子view。这些子view大多数不会一直处于界面上,只是在某些情况下才会出现,例如登陆失败的提示view,上传附件成功的提示view,网络失败的提示view等。但是虽然这些view很少出现,但是我们却常常一直把它们放在内存中。另外,当收到内存警告时,我们只能自己手工把这些view从super view中去掉。

在iOS 5.0及以后,iOS为UIViewController类添加了新的属性和方法:



@property(nonatomic,readonly) NSArray *childViewControllers



- (void)addChildViewController:(UIViewController *)childController

- (void) removeFromParentViewController

- (void)transitionFromViewController::::::

- (void)willMoveToParentViewController:(UIViewController *)parent

- (void)didMoveToParentViewController:(UIViewController *)parent



这样,就能够将一个页面中的UIViewController控制起来,而不是混乱的共用一个UIViewController

,最重要的是,编程习惯的革命:降低了功能的耦合度!



写这篇博客,仅仅是讲以上5个方法!仅此而已。因为当我在百度或者谷歌中,输入以上5个方法的名字后,查出来的,并没有告诉这5个方法起到如何的作用?如何使用?



所以,我仅仅是想从API角度来谈一谈,这5个方法。

废话不多说了!



先搞清楚一个今天提到的概念:



[父视图控制器 addChildViewController:子视图控制器];



在此,图控制器A添加了另一个图控制器B,那么A充当父视图控制器,B充当子视图控制器。父视图控制器充当了视图控制器容器的角色。



addChildViewController方法:



- (void)addChildViewController:(UIViewController *)childController

向视图控制器容器中添加子视图控制器



childController:子视图控制器



当要添加的子视图控制器已经包含在视图控制器容器中,那么,相当于先从父视图控制器中删除,然后重新添加到父视图控制器中。



removeFromParentViewController 方法



- (void)removeFromParentViewController

从父视图控制器中删除。



transitionFromViewController 方法



- (void)transitionFromViewController:(UIViewController *)fromViewControllertoViewController:(UIViewController *)toViewController duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion



交换两个子视图控制器的位置(由于添加的顺序不同,所以子试图控制器在父视图控制器中存在层次关系)



fromViewController:当前显示的子试图控制器,将被替换为非显示状态

toViewController:将要显示的子视图控制器

duration:交换动画持续的时间,单位秒

options:动画的方式

animations:动画Block

completion:完成后执行的Block



willMoveToParentViewController 方法



- (void)willMoveToParentViewController:(UIViewController *)parent

当一个视图控制器从视图控制器容器中被添加或者被删除之前,该方法被调用



parent:父视图控制器,如果没有父视图控制器,将为nil





注意点:

1.当我们向我们的视图控制器容器中调用removeFromParentViewController方法时,必须要先调用该方法,且parent参数为nil:

[将要删除的视图控制器 willMoveToParentViewController:nil];

2.当我们调用addChildViewController方法时,在添加子视图控制器之前将自动调用该方法。所以,就不需要我们显示调用了。



didMoveToParentViewController 方法



- (void)didMoveToParentViewController:(UIViewController *)parent

当从一个视图控制容器中添加或者移除viewController后,该方法被调用。

parent:父视图控制器,如果没有父视图控制器,将为nil



当我们向我们的视图控制器容器(就是父视图控制器,它调用addChildViewController方法加入子视图控制器,它就成为了视图控制器的容器)中添加(或者删除)子视图控制器后,必须调用该方法,告诉iOS,已经完成添加(或删除)子控制器的操作。



removeFromParentViewController 方法会自动调用了该方法,所以,删除子控制器后,不需要在显示的调用该方法了。

其实,这几个方法中的API说明,看的还懂。



最后,



关于willMoveToParentViewController方法和didMoveToParentViewController方法的使用



1.这两个方法用在子试图控制器交换的时候调用!即调用transitionFromViewController 方法时,调用。



2.当调用willMoveToParentViewController方法或didMoveToParentViewController方法时,要注意他们的参数使用:

当某个子视图控制器将从父视图控制器中删除时,parent参数为nil。

即:[将被删除的子试图控制器 willMoveToParentViewController:nil];

当某个子试图控制器将加入到父视图控制器时,parent参数为父视图控制器。

即:[将被加入的子视图控制器 didMoveToParentViewController:父视图控制器];



3.无需调用[子视图控制器 willMoveToParentViewController:父视图控制器]方法。因为我们调用[父视图控制器 addChildViewController:子视图控制器]时,已经默认调用了。

只需要在transitionFromViewController方法后,调用[子视图控制器didMoveToParentViewController:父视图控制器];



4.无需调用[子视图控制器 didMoveToParentViewController:父视图控制器]方法。因为我们调用

[子视图控制器 removeFromParentViewController]时,已经默认调用了。

只需要在transitionFromViewController方法之前调用:[子视图控制器 willMoveToParentViewController:nil]。

相关推荐

    iOS5 UIViewController 新特性

    在iOS5中,UIViewController引入了一系列的新特性和改进,极大地增强了开发者处理界面和控制视图的能力。以下是对这些新特性的详细说明: 1. **Storyboards**:iOS5引入了Storyboard的概念,这是一种全新的界面设计...

    UIViewcontoller的新方法测试_demo

    在这个名为"UIViewcontoller的新方法测试_demo"的项目中,我们将探讨这些新方法,并通过实际代码示例来理解它们的用法。 首先,我们要了解`UIViewController`的一个重要更新:`childViewControllers`属性。在iOS ...

    ios Swapping View

    在iOS开发中,Swapping View通常指的是在应用中动态替换视图控制器或视图的过程,以便为用户提供不同的界面或功能。这种技术在实现导航、页面切换或者内容更新时非常常见。下面将详细介绍如何在iOS中实现Swapping ...

    IOS应用源码——SFContainerViewController for iOS.rar

    这通常涉及到 `-addChildViewController:`、`-removeChildViewController:` 和 `-transitionFromViewController:toViewController:duration:options:animation:completion:` 等方法的使用。 2. **视图管理**:源码...

    ios-SkChildViewController.zip

    在这个类中,你需要重写`addChildViewController:`、`removeFromParentViewController:`等方法,以添加和移除子控制器。 2. 添加子控制器:在适当的时候,例如在初始化或根据用户操作,调用`addChildViewController...

    IOS应用源码——动态tab bar.zip

    同样,也可以通过`- (void)addChildViewController:(UIViewController *)childController`添加新的ViewController并更新Tab Bar。 3. **使用Notification或Delegate**:为了在适当的时间更新Tab Bar,可以监听特定...

    多种view视图切换效果.zipIOS应用例子源码下载

    - **UIStoryboardSegue**: iOS中的UIStoryboardSegue类提供了在Storyboard之间或内部进行视图控制器(UIViewController)切换的途径。通过拖拽和配置UIStoryboardSegue,可以实现简单的模态或推入视图切换。 - **...

    详解iOS项目基本框架搭建

    在iOS项目开发中,构建一个稳定且高效的基本框架至关重要,它为后续的功能开发和维护提供了坚实的基础。本文将深入探讨iOS项目基本框架搭建,特别是导航架构设计,以及如何使用TabBar + NavigationController来构建...

    Guide-maste新手指引浮层

    - 对于iOS,可以使用UIWindow或者UIViewController的addChildViewController方法叠加视图,使用UserDefaults存储用户状态。 4. 用户反馈与优化: - 收集用户反馈:通过用户测试和数据分析,了解用户对新手引导的...

    隐式切换主控制器代码

    在iOS开发中,主控制器(通常指`UIViewController`或其子类)是应用程序的核心部分,它负责管理用户界面和业务逻辑。"隐式切换主控制器代码"是一个高级编程技巧,用于在运行时动态地更改应用的主视图控制器,而无需...

    抽屉效果,侧滑带弹回,

    而在iOS中,可以使用`UISwipeGestureRecognizer`配合`UIPanGestureRecognizer`来处理手势,以及`UIViewController`的`addChildViewController`和`view addSubview:`方法来添加和管理抽屉视图。在Web开发中,我们可以...

    XLPageViewController:一个开放,高度可定制化的分页视图控制器

    在iOS应用设计中,分页视图控制器常常用于实现多页面滑动浏览的效果,例如在很多新闻应用、社交应用或者设置界面中都能看到这种设计。XLPageViewController的出现,使得开发者能够更加轻松地构建这样的功能,并根据...

    PageScrollTabbarContrller:左右滑动Controller来切换tabbar

    这通常通过addChildViewController和removeChildViewController等方法实现。 4. **布局与约束**:由于滑动tabbar需要在屏幕底部固定,所以项目的布局文件(可能是storyboard或xib)会包含关于tabbar位置和大小的...

    ContainerViewController

    容器视图控制器是Apple iOS SDK中的一个强大特性,它允许开发者在一个单一的UIViewController实例中组合、管理多个子视图控制器,从而实现复杂的界面布局和交互。 在iOS应用开发中,Container View Controller经常...

Global site tag (gtag.js) - Google Analytics