美文网首页iOS基本功
OC--UIViewController基础知识整理

OC--UIViewController基础知识整理

作者: 啊哈呵 | 来源:发表于2017-03-11 09:28 被阅读254次

    alloc init

    //这个 方法是在viewdidload之前加载的,以nib文件加载必然会调用此方法,但是代码加载也是会自动调用的,因此可以将一些数组创建,标题命名等初始化操作写在这里
    //1.如果在初始化UIViewController指定了xib文件名,就会根据传入的xib文件名加载对应的xib文件
    //2.如果没有明显地传xib文件名([[MJViewController alloc] init];),就会加载跟UIViewController同名的xib文件
    //3.如果没有找到相关联的xib文件,就会创建一个空白的UIView,然后赋值给UIViewController的view属性
    - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER;
    //NSCoding协议
    - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
    //这个UIViewController的nib名字
    @property(nullable, nonatomic, readonly, copy) NSString *nibName;
    //这个UIViewController的nibBundle
    @property(nullable, nonatomic, readonly, strong) NSBundle *nibBundle;
    //这个UIViewControlle所在的Storyboar
    @property(nullable, nonatomic, readonly, strong) UIStoryboard *storyboard NS_AVAILABLE_IOS(5_0);
    

    loadView

    //如果获取self.view,如果没有现实[self loadView],就是调用Subclasses的loadView方法。
    @property(null_resettable, nonatomic,strong) UIView *view;
    
    //loadView里面自定义self.view
    - (void)loadView;
    
    //iOS9之前
    //有些时候因为需要手动调用loadview
    //但是有风险,系统不再调用viewDidLoad
    //所以手动调用loadview是错误的
    
    //iOS9之后
    //出现了loadViewIfNeeded解决了这个问题
    //调用这个方法视图会创建出来并且不会忽略viewDidLoad
    - (void)loadViewIfNeeded NS_AVAILABLE_IOS(9_0);
    
    //返回加载完的self.view
    @property(nullable, nonatomic, readonly, strong) UIView *viewIfLoaded NS_AVAILABLE_IOS(9_0);
    
    //view是否加载完成
    @property(nonatomic, readonly, getter=isViewLoaded) BOOL viewLoaded ;
    - (BOOL)isViewLoaded ;
    

    Storyboary相关

    //Storyboar跳转摆好的界面
    //identifier:设置好的界面连线(就是Storyboar中VC与VC那条线)
    //sender:发送者
    - (void)performSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
    
    //看看能不能跳转,主要是看identifier对不对
    - (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(nullable id)sender NS_AVAILABLE_IOS(6_0);
    
    
    //准备处理,
    //segue:用来判断是哪个segue,里面有identifier、sourceViewController、destinationViewController可以各种操作
    //sender:发送者
    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender NS_AVAILABLE_IOS(5_0);
    
    //Unwind Segue相关,(不明白,留着慢慢玩)
    - (BOOL)canPerformUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(id)sender NS_AVAILABLE_IOS(6_0);
    - (NSArray<UIViewController *> *)allowedChildViewControllersForUnwindingFromSource:(UIStoryboardUnwindSegueSource *)source NS_AVAILABLE_IOS(9_0);
    - (nullable UIViewController *)childViewControllerContainingSegueSource:(UIStoryboardUnwindSegueSource *)source NS_AVAILABLE_IOS(9_0);
    - (nullable UIViewController *)viewControllerForUnwindSegueAction:(SEL)action fromViewController:(UIViewController *)fromViewController withSender:(nullable id)sender NS_DEPRECATED_IOS(6_0, 9_0);
    - (void)unwindForSegue:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC NS_AVAILABLE_IOS(9_0);
    - (nullable UIStoryboardSegue *)segueForUnwindingToViewController:(UIViewController *)toViewController fromViewController:(UIViewController *)fromViewController identifier:(nullable NSString *)identifier NS_DEPRECATED_IOS(6_0, 9_0);
    

    生命周期函数

    //系统的loadview完成后,执行viewDidLoad
    - (void)viewDidLoad;
    //这几个生命周期方法,必须熟悉
    - (void)viewWillAppear:(BOOL)animated;
    - (void)viewDidAppear:(BOOL)animated;
    - (void)viewWillDisappear:(BOOL)animated;
    - (void)viewDidDisappear:(BOOL)animated;
    - (void)viewWillLayoutSubviews NS_AVAILABLE_IOS(5_0);
    - (void)viewDidLayoutSubviews NS_AVAILABLE_IOS(5_0);
    - (void)didReceiveMemoryWarning;
    

    单个viewController的生命周期

    1、initWithCoder:(NSCoder *)aDecoder:(如果使用storyboard或者xib)
    2、loadView:加载view
    3、viewDidLoad:view加载完毕
    4、viewWillAppear:控制器的view将要显示
    5、viewWillLayoutSubviews:控制器的view将要布局子控件
    6、viewDidLayoutSubviews:控制器的view布局子控件完成,这期间系统可能会多次调用viewWillLayoutSubviews 、    viewDidLayoutSubviews 俩个方法
    7、viewDidAppear:控制器的view完全显示
    8、viewWillDisappear:控制器的view即将消失的时候
    9、这期间系统也会调用viewWillLayoutSubviews 、viewDidLayoutSubviews 两个方法
    10、viewDidDisappear:控制器的view完全消失的时候
    

    多个viewControllers跳转

    当我们点击push的时候首先会加载下一个界面然后才会调用界面的消失方法
    1、initWithCoder:(NSCoder *)aDecoder:ViewController2 (如果用xib创建的情况下)
    2、loadView:ViewController2
    3、viewDidLoad:ViewController2
    4、viewWillDisappear:ViewController1 将要消失
    5、viewWillAppear:ViewController2 将要出现
    6、viewWillLayoutSubviews ViewController2
    7、viewDidLayoutSubviews ViewController2
    8、viewWillLayoutSubviews:ViewController1
    9、viewDidLayoutSubviews:ViewController1
    10、viewDidDisappear:ViewController1 完全消失
    11、viewDidAppear:ViewController2 完全出现
    
    //nav标题
    @property(nullable, nonatomic,copy) NSString *title;
    
    @property(nullable,nonatomic,weak,readonly) UIViewController *parentViewController;//父控制器
    @property(nullable, nonatomic,readonly) UIViewController *presentedViewController;//第二者
    @property(nullable, nonatomic,readonly) UIViewController *presentingViewController;//第一者
    
    //例子
    UIViewController *vcB = [[UIViewController alloc] init];
    [self addChildViewController:vcB];
    NSLog(@"%@", vcB.parentViewController);//self
    
    UIViewController *vcB = [[UIViewController alloc] init];
    [self presentViewController:vcB animated:YES completion:^{}];
        
    NSLog(@"%@", self.presentedViewController);//vcB
    NSLog(@"%@", self.presentingViewController);//nil
        
    NSLog(@"%@", vcB.presentedViewController);//nil
    NSLog(@"%@", vcB.presentingViewController);//self
    
    
    //UIViewController的edgesForExtendedLayout属性默认值是UIRectEdgeAll,指定控制器将它的视图延伸到屏幕的边缘并在bar下面。如果属性值为:UIRectEdgeNone,控制器视图遇到bar的边界就不延伸了。
    @property(nonatomic,assign) UIRectEdge edgesForExtendedLayout ; // Defaults to UIRectEdgeAll
    
    //UIViewController的extendedLayoutIncludesOpaqueBars属性可以控制以上属性的有效性,默认值为NO,指定edgesForExtendedLayout在遇到不透明的bar时无效,即不延展。设置值为YES,则在遇到透明或不透明的bar情况下都会延展。
    @property(nonatomic,assign) BOOL extendedLayoutIncludesOpaqueBars ; // Defaults to NO, but bars are translucent by default on 7_0.
    
    //UIViewController的automaticallyAdjustsScrollViewInsets默认为YES,指定控制器在有UIScrollView及其子类并且在有导航栏或工具栏或标签栏情况下,会自动调整其contentInset属性。如果是导航栏contentInset.top = 64,如果是标签栏contentInset.bottom = 44.
    //可以将该属性设置为NO,取消这种行为。
    @property(nonatomic,assign) BOOL automaticallyAdjustsScrollViewInsets ; // Defaults to YES
    

    UIStatusBar相关的设置iOS-UIStatusBar详细总结

    - (UIStatusBarStyle)preferredStatusBarStyle ;
    - (BOOL)prefersStatusBarHidden ;
    - (UIStatusBarAnimation)preferredStatusBarUpdateAnimation
    

    UIModalTransitionStyle是弹出模态ViewController时的四种动画风格

    typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {
        UIModalTransitionStyleCoverVertical = 0,//是从底部滑入,默认
        UIModalTransitionStyleFlipHorizontal ,  //是水平翻转
        UIModalTransitionStyleCrossDissolve,    //是交叉溶解
        UIModalTransitionStylePartialCurl,      //是翻书效果
    };
    

    UIModalPresentationStyle是弹出模态ViewController时弹出风格
    Present ViewController详解

    typedef NS_ENUM(NSInteger, UIModalPresentationStyle) {
        UIModalPresentationFullScreen = 0,      //是弹出VC时,VC充满全屏
        UIModalPresentationPageSheet ,          //是如果设备横屏,VC的显示方式则从横屏下方开始
        UIModalPresentationFormSheet ,          //是VC显示都是从底部,宽度和屏幕宽度一样
        UIModalPresentationCurrentContext ,     //是VC的弹出方式和VC父VC的弹出方式相同
        UIModalPresentationCustom ,             //自定义
        UIModalPresentationOverFullScreen ,     //
        UIModalPresentationOverCurrentContext , //
        UIModalPresentationPopover ,            //
        UIModalPresentationNone ,               //
    };
    

    如何present一个半透明的ViewController

    - (void)btnOnClick:(id)sender {
        UIViewController *test = [[UIViewController alloc] init];
        self.definesPresentationContext = YES;
        test.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:.4];
        test.modalPresentationStyle = UIModalPresentationOverCurrentContext;
        [self presentViewController:test animated:YES completion:nil];
    }
    

    UIContentContainer
    iOS8之后,加入了新的一组协议,UIViewController对这组协议提供了默认的实现,我们自定义ViewConttroller的时候可以重写这些方法来调整视图布局。(先放放,等有时间在研究使用)

    @protocol UIContentContainer <NSObject>
    
    @property (nonatomic, readonly) CGSize preferredContentSize NS_AVAILABLE_IOS(8_0);
    
    //当一个容器ViewController的ChildViewController的preferredContentSize值改变时,UIKit会调用这个方法告诉当前容器ViewController。我们可以在这个方法里根据新的Size对界面进行调整。
    - (void)preferredContentSizeDidChangeForChildContentContainer:(id <UIContentContainer>)container NS_AVAILABLE_IOS(8_0);
    
    //当一个容器ViewController的ChildViewController的systemLayoutFittingSize值改变时,UIKit会调用这个方法告诉当前容器ViewController。我们可以在这个方法里根据新的Size对界面进行调整。
    - (void)systemLayoutFittingSizeDidChangeForChildContentContainer:(id <UIContentContainer>)container NS_AVAILABLE_IOS(8_0);
    
    //viewWillTransitionToSize:withTransitionCoordinator:调用的时候
    - (CGSize)sizeForChildContentContainer:(id <UIContentContainer>)container withParentContainerSize:(CGSize)parentSize NS_AVAILABLE_IOS(8_0);
    
    //TransitionToSize:动画方面触发?
    - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator NS_AVAILABLE_IOS(8_0);
    
    //什么鬼啊?
    - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withTransitionCoordinator:(id <UIViewControllerTransitionCoordinator>)coordinator NS_AVAILABLE_IOS(8_0);
    
    @end
    

    相关文章

      网友评论

        本文标题:OC--UIViewController基础知识整理

        本文链接:https://www.haomeiwen.com/subject/zusggttx.html