56

iOS文档补完计划--UIViewController

 4 years ago
source link: https://www.tuicool.com/articles/ZZVBFzy
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
jim2yaj.png!web

目录

  • UIViewController

    • 职责

    • 视图管理

    • 处理与视图相关的通知

    • 实现容器视图控制器

    • 内存管理

    • 生命周期

  • 以代码的方式创建一个控制器

    • initWithNibName:bundle:

    • initWithCoder:

  • 管理视图

    • view

    • viewLoaded

    • loadView

    • viewDidLoad

    • loadViewIfNeeded

    • viewIfLoaded

    • title

    • preferredContentSize

  • 呈现视图控制器

    • modalPresentationStyle

    • modalTransitionStyle

    • showViewController:sender:

    • presentViewController:animated:completion:

    • dismissViewControllerAnimated:completion:

  • 响应View事件

    • View XX Appear

    • beingDismissed && beingPresented

    • Moving XX ParentViewController

  • 安全区域

    • additionalSafeAreaInsets

    • viewSafeAreaInsetsDidChange

  • 布局视图

    • edgesForExtendedLayout

    • extendedLayoutIncludesOpaqueBars

    • updateViewConstraints

    • viewWill/DidLayoutSubviews

  • 子视图控制器

    • childViewControllers

    • addChildViewController:

    • removeFromParentViewController

    • transitionFromViewController:toViewController:duration:options:animations:completion:

    • shouldAutomaticallyForwardAppearanceMethods

    • AppearanceTransition

  • 响应容器事件

    • willMoveToParentViewController

    • didMoveToParentViewController

  • 获取其他控制器

    • presentingViewController && presentedViewController

    • parentViewController

    • navigationController

    • splitViewController

    • tabBarController

  • 处理内存警告

    • didReceiveMemoryWarning

  • 协调系统手势

    • preferredScreenEdgesDeferringSystemGestures

    • childViewControllerForScreenEdgesDeferringSystemGestures

  • 管理状态栏

    • childViewControllerForStatusBarStyle

    • childViewControllerForStatusBarHidden

    • preferredStatusBarStyle

    • prefersStatusBarHidden

    • modalPresentationCapturesStatusBarAppearance

    • preferredStatusBarUpdateAnimation

    • setNeedsStatusBarAppearanceUpdate

  • 配置导航入口

    • navigationItem

    • hidesBottomBarWhenPushed

    • toolbarItems

    • tabBarItem

  • 编辑行为

    • editing

    • setEditing:animated:

    • editButtonItem

UIViewController

  • 职责

  1. 更新视图内容

  2. 响应交互

  3. 调整入口View布

  4. 与程序中其他对象(包括其他控制器)进行协调

UIViewController 作为 UIResponder 、被插入响应链之间。如果其持有的视图中没有一个可以处理某事件、控制器可以选择自行处理或者传递给父视图。

控制器很少单独被使用、我们通常使用多个控制器进行相互的跳转作业。

  • 视图管理

根View主要充当视图层次结构的其余部分的容器。

根View的大小和位置由拥有它的对象决定,该对象要么是视图控制器,要么是应用程序的Window。

Window所拥有的视图控制器是应用程序的根View控制器,它的视图是用来填充Window的。

View属性是懒加载的、有几种方式可以指定ViewController的View:

  1. Storyboard

    可以指定视图及其与视图控制器的连接。

    你也指定视图控制器之间的关系和segue。

  2. Nib

    使用Nib文件为视图控制器指定单个视图控制器的视图。

    但不允许定义segue或视图控制器之间的关系。

  3. loadView方法

    以代码方式创建视图层次结构,并将该层次结构的根视图分配给视图控制器的 View属性

所有的方式都能导向相同的结果:创建VIew并且通过ViewController.view属性进行公开。

需要注意的是

多个Controller使用同一个 Storyboard 或者 Nib 作为View属性时、他们会持有单独的副本。

而代码方式、你必须确保View不会被多个VC持有。

  • 处理与视图相关的通知

视图的可见性

当视图的可见性发生变化时,视图控制器会自动调用它自己的方法,以便子类可以对变化做出响应。比如 viewWillAppear 在展示之前进行设置、 viewWillDisappear: 在消失之前进行状态保存或更改。

euI7BrQ.png!web
  • 实现容器视图控制器

我们的日常开发中常有这样一种需求,通过切换标签来切换不同的页面,如果在一个 controller 管理这些 view 的话,代码就显得耦合度过高,也与 Apple 的 MVC 模式不符合,Apple 推荐一个 controller 管理一个 view。这样做有三个好处:

1.无疑,对页面中的逻辑更加分明了。相应的View对应相应的ViewController。

2.当某个子View没有显示时,将不会被Load,减少了内存的使用。

3.当内存紧张时,没有Load的View将被首先释放,优化了程序的内存释放机制。

4.在子VC上调用 self.navigationController 可以传递给父VC。(UIPageController上特别好用)

像这样使用

//添加
[self addChildViewController:sfViewControllr];
[self.view addSubview:sfViewControllr.view];
sfViewControllr.view.frame = CGRectMake(0, 300, 1, 1);

//移除
[sfViewControllr didMoveToParentViewController:self];

如果只是 [self.view addSubview:sfViewControllr.view]; 的方式用另一个 controller 来控制,但是这样会产生一个新的问题:直接 add 进去的subView不在 viewController的 view hierarchy 内,事件不会正常传递,如:旋转、触摸等,属于危险操作违背CocoaTouch开发的设计MVC原则,viewController应该且只应该管理一个view hierarchy。

  • 内存管理

内存是iOS中的关键资源,视图控制器提供了内置支持,在关键时刻减少内存占用。UIViewController类通过它的 didReceiveMemoryWarning 方法提供一些低内存条件的自动处理,这些方法释放不需要的内存。

  • 生命周期

  1. +[ViewController load]

  2. +[ViewController initialize]

  3. -[ViewController init]

  4. -[ViewController loadView]

  5. -[ViewController viewDidLoad]

  6. -[ViewController viewWillAppear:]

  7. -[ViewController updateViewConstraints]

  8. -[ViewController viewWillLayoutSubviews]

  9. -[ViewController viewDidLayoutSubviews]

  10. -[ViewController viewDidAppear:]

  11. -[ViewController dealloc]

其中1和2严格意义上来讲应该不算在内

以代码的方式创建一个控制器

  • - initWithNibName:bundle:

通过代码的方式实例化一个IB方式创建的控制器

- (instancetype)initWithNibName:(NSString *)nibNameOrNil 
                         bundle:(NSBundle *)nibBundleOrNil;

TestViewController *tvc = [[TestViewController alloc] initWithNibName:@"xx" bundle:nil]; // 注意xib名字不要后缀

需要指定xx.xib的file’s owner的Custom Class为TestViewController,并且把file’s owner的view指定为其中的一个view

  • - initWithCoder:

在IB中创建的类、但在xocde中被实例化时被调用

- (instancetype)initWithCoder:(NSCoder *)aDecoder;

管理视图

  • view

容器视图

@property(nonatomic, strong) UIView *view;
  1. 这个属性是来加载的、当你访问时如果为nil、将调用 loadView 方法并返回 view

  2. 每一个VC、都必须是该View的唯一一个持有者。(例外情况是通过 addChildViewController: 方法添加后、将vc.view add给另一个vc)

  3. 你可以通过 isViewLoaded 方法来检测当前vc是否已经持有视图。(这样不会触发懒加载)。

  4. VC有权在低内存情况下以及VC最终释放时、释放这个属性。

  • viewLoaded

self.view 是否有值

@property(nonatomic, readonly, getter=isViewLoaded) BOOL viewLoaded;

这个属性的检测不会触发 view 属性的懒加载。

  • - loadView

创建容器视图

- (void)loadView;

view 属性被访问但本身没有值时触发、你可以在这里自定义 view 属性的视图。

  1. 永远不要直接调用这个方法。

  2. 如果使用 nib 、该方法从 nib 中加载视图。如果不是、则直接创建一个 UIView

  3. 如果使用IB来创建VC、不要覆盖这个方法。

  4. 如果自定义 view 。您创建的视图应该是唯一的实例,不应该与任何其他视图控制器对象共享。此方法的自定义实现不应调用super。

  5. 如果想对 view 进行其余的动作(添加subVIew等等 )、请在 viewDidLoad`中执行。

通常用在进到vc就要切换view的时候使用、比如进来就是一张图片啊、webView啊之类。

  • - viewDidLoad

loadView 后执行。表示此时已经有view属性

- (void)viewDidLoad;

不管视图层次结构是从nib文件加载的还是在loadView方法中以编程方式创建的,都会调用此方法。

通常在这里对view进行进一步配置。

  • loadViewIfNeeded

主动尝试调用loadView

- (void)loadViewIfNeeded;

正常如果我们主动调用 [self loadView]; 是不会触发 viewDidLoad 的、但这个方法可以。

不过似乎必须要 [self isViewLoaded] == NO 才行

  • viewIfLoaded

返回vc的view。并且不会触发懒加载

@property(nonatomic, readonly, strong) UIView *viewIfLoaded;

如果没有则返回nil

  • title

标题

@property(nonatomic, copy) NSString *title;

如果VC有一个有效的导航项或标签栏项,为该属性赋值将更新这些对象的标题文本。

相当于同时设置了 tabBarItem.titlenavigationItem.title

  • preferredContentSize

我们可以使用preferredContentSize来设置我们期望的childViewController的界面的大小

@property(nonatomic) CGSize preferredContentSize;

没太理解怎么用、有明白的大佬举个例子?

似乎在ipad上有用

呈现视图控制器

  • modalPresentationStyle

模态跳转的样式

@property(nonatomic, assign) UIModalPresentationStyle modalPresentationStyle;

UIModalPresentationStyle 为一个枚举类型

在iPhone和iPod touch上面系统始终已UIModalPresentationFullScreen模式显示presented VC。(哈哈哈。很气、我试了半天差了好多资料最后看到这句话)

typedefNS_ENUM(NSInteger, UIModalPresentationStyle) {

        UIModalPresentationFullScreen =0,//全屏覆盖

        UIModalPresentationPageSheet,//弹出VC时,presented VC的高度和当前屏幕高度相同,宽度和竖屏模式下屏幕宽度相同,剩余未覆盖区域将会变暗并阻止用户点击,这种弹出模式下,竖屏时跟 UIModalPresentationFullScreen的效果一样,横屏时候两边则会留下变暗的区域。

        UIModalPresentationFormSheet,// presented VC的高度和宽度均会小于屏幕尺寸,presented VC居中显示,四周留下变暗区域。

        UIModalPresentationCurrentContext,//这种模式下,presented VC的弹出方式和presenting VC的父VC的方式相同。

        UIModalPresentationCustom,//自定义视图展示风格,由一个自定义演示控制器和一个或多个自定义动画对象组成。符合UIViewControllerTransitioningDelegate协议。使用视图控制器的transitioningDelegate设定您的自定义转换。

        UIModalPresentationOverFullScreen,//如果视图没有被填满,底层视图可以透过

        UIModalPresentationOverCurrentContext,//视图全部被透过

        UIModalPresentationPopover,

        UIModalPresentationNone ,

    };
  • modalTransitionStyle

设置过渡动画样式

@property(nonatomic, assign) UIModalTransitionStyle modalTransitionStyle;

在通过 presentViewController:animated:completion: 进行模态跳转时的专场动画样式。默认 UIModalTransitionStyleCoverVertical

UIModalTransitionStyle 是一个枚举类型

typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {

        UIModalTransitionStyleCoverVertical =0,//从底部滑入

        UIModalTransitionStyleFlipHorizontal,//水平翻转

        UIModalTransitionStyleCrossDissolve,//交叉溶解

        UIModalTransitionStylePartialCurl  NS_ENUM_AVAILABLE_IOS(3_2),//翻页效果

};
  • showViewController:sender:

大一统的跳转方法

- (void)showViewController:(UIViewController *)vc 
                    sender:(id)sender;

- (void)showDetailViewController:(UIViewController *)vc 
                          sender:(id)sender;

全能型界面切换的方法,它能根据当前的试图控制器情况来决定是用navVC的push方法还是普通VC的Modal方式来切换界面。

showViewController是苹果“大一统”编程思想的体现,无论是在UINavigationController还是在UISplitViewController管理下,都可以使用showViewController去跳转。系统底层会实现两种管理模式下的对应跳转。另外如果这两种方式都未实现,就会以modal方式跳转。

  1. 当前界面是Nav的子VC时

    它会用push方式切换。

  2. 当前界面为Modal的界面,

    就会用modal方式切换。

但也有些缺陷、比如不能设置是否执行动画、获取不到完成的block。

一般情况下,horizontally compact(iphone) 环境下,意义不大(因为不太需要考虑 UISplitViewController )。

  • - presentViewController:animated:completion:

以模态方式呈现一个VC

- (void)presentViewController:(UIViewController *)viewControllerToPresent 
                     animated:(BOOL)flag 
                   completion:(void (^)(void))completion;

在水平规则环境中,视图控制器以 modalPresentationStyle 属性指定的样式表示。

任何情况下都可以通过 modalTransitionStyle 属性进行转场设置。

viewDidAppear 之后调用 completion 回调。

  • - dismissViewControllerAnimated:completion:

退出一个由模态方式展示的VC

- (void)dismissViewControllerAnimated:(BOOL)flag 
                           completion:(void (^)(void))completion;

viewDidDisappear 之后调用 completion 回调。

响应View事件

  • View XX Appear

视图的显示与隐藏

- (void)viewWillAppear:(BOOL)animated;    // 视图即将显示时调用
- (void)viewDidAppear:(BOOL)animated;     // 视图已经显示时调用
- (void)viewWillDisappear:(BOOL)animated; // 视图将要消失时调用
- (void)viewDidDisappear:(BOOL)animated; // 视图已经消失时调用

这张图应该很清楚了

euI7BrQ.png!web

.h文件里说 这四个方法默认什么都不做 、但是文档里说 务必调用super方法

  • beingDismissed && beingPresented

视图是否正在消失/显示

@property(nonatomic, readonly, getter=isBeingPresented) BOOL beingPresented NS_AVAILABLE_IOS(5_0); //正在显示
@property(nonatomic, readonly, getter=isBeingDismissed) BOOL beingDismissed NS_AVAILABLE_IOS(5_0);//正在消失
  • Moving XX ParentViewController

视图是否正在从父VC来/向父VC去

@property(nonatomic, readonly, getter=isMovingToParentViewController) BOOL movingToParentViewController NS_AVAILABLE_IOS(5_0); //向父VC去
@property(nonatomic, readonly, getter=isMovingFromParentViewController) BOOL movingFromParentViewController NS_AVAILABLE_IOS(5_0); //从父VC来

安全区域

  • additionalSafeAreaInsets

修改安全区域的内嵌程度

@property(nonatomic) UIEdgeInsets additionalSafeAreaInsets;

比如如果 SafeAreaInset 值为(20,0,0,0),那么页面上的TableVIew可能会下移20个单位。

此时设置additionalSafeAreaInsets属性值为(-20,0,0,0),则SafeAreaInsets不会对adjustedContentInset值产生影响。以便正常显示。

有兴趣可以看看 《iOS 11 安全区域适配总结》

  • - viewSafeAreaInsetsDidChange

当VC的 safeAreaInsets 发生改变是被调用

- (void)viewSafeAreaInsetsDidChange;

布局视图

  • edgesForExtendedLayout

指定view的边(上、下、左、右)延伸到整个屏幕

@property(nonatomic, assign) UIRectEdge edgesForExtendedLayout;

默认值是UIRectEdgeAll, 意味着view会被拓展到整个屏幕。

它只有当viewController被嵌到别的container view controller中时才会起作用

《edgesForExtendedLayout浅淡》

  • extendedLayoutIncludesOpaqueBars

如果status bar是不透明的,view不会被延伸到status bar,除非extendedLayoutIncludesOpaqueBars = YES;

@property(nonatomic, assign) BOOL extendedLayoutIncludesOpaqueBars;

默认为NO。在iOS 7.0中,bars默认是半透明的。

  • updateViewConstraints

当自身view属性的布局被修改时被自动调用

- (void)updateViewConstraints;

这个方法默认的实现是调用对应View的 -updateConstraints

调用[super updateViewConstraints]作为实现的最后一步。

  • viewWill/DidLayoutSubviews

重新布局子View前/后调用

- (void)viewWillLayoutSubviews NS_AVAILABLE_IOS(5_0);
- (void)viewDidLayoutSubviews NS_AVAILABLE_IOS(5_0);

这两个方法的默认实现什么都不做

其中 viewDidLayoutSubviews 可以获取子控件正确的frame

子视图控制器

具体的作用可以回去看看《UIViewController》 >>>《实现容器视图控制器》部分的解释。

  • childViewControllers

存放子VC的数组

@property(nonatomic, readonly) NSArray*childViewControllers;
  • - addChildViewController:

添加子VC

- (void)addChildViewController:(UIViewController *)childController;
  • - removeFromParentViewController

从父VC上移除

- (void)removeFromParentViewController;
  • - transitionFromViewController:toViewController:duration:options:animations:completion:

通过动画的方式操作两个子VC

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

《iOS 中使用ViewController控制转场的各种方法》

  • shouldAutomaticallyForwardAppearanceMethods

是否将 appearance callbacks 事件传递给子VC

@property(nonatomic, readonly) BOOL shouldAutomaticallyForwardAppearanceMethods;

appearance callbacks 基本上指 viewWillDisappear,viewDidDisappear 之类方法。

默认为YES、你可以重载以禁用

- (BOOL)shouldAutomaticallyForwardAppearanceMethods
{
    return NO;
}
  • AppearanceTransition

调起指定的 appearance callbacks

- (void)beginAppearanceTransition:(BOOL)isAppearing 
                         animated:(BOOL)animated;
- (void)endAppearanceTransition;

动传递的时候你并不能直接去调用 childviewWillAppear 或者 viewDidAppear 这些方法,而是需要使用 beginAppearanceTransition:animated:endAppearanceTransition 接口来间接触发那些appearance callbacks

且begin和end 必须成对出现

[content beginAppearanceTransition:YES animated:animated] 触发content的 viewWillAppear

[content beginAppearanceTransition:NO animated:animated] 触发content的 viewWillDisappear

和他们配套的 [content endAppearanceTransition] 分别触发 viewDidAppearviewDidDisappear

响应容器事件

  • - willMoveToParentViewController

将要添加到容器VC时调用

- (void)willMoveToParentViewController:(UIViewController *)parent;

BVC 通过 addChildViewControllerA 、接口建立了逻辑上的父子关系, BVC 可以通过 parentViewController ,访问 AVCaddChildViewController: 接口的逻辑中会自动调用 [BVC willMoveToParentViewController:self] ;

  • didMoveToParentViewController

从容器VC上移除时调用

- (void)didMoveToParentViewController:(UIViewController *)parent;

同上、在调用 removeFromParentViewController 时内部会调用 [BVC didMoveToParentViewController:nil]

获取其他控制器

  • presentingViewController && presentedViewController

presen 别人的控制器、被 presen 的控制器

@property(nonatomic, readonly) UIViewController *presentingViewController;//来自
@property(nonatomic, readonly) UIViewController *presentedViewController;//去往

假设从A控制器通过present的方式跳转到了B控制器,那么 A.presentedViewController 就是B控制器;B.presentingViewController 就是A控制器。

  • parentViewController

父VC

@property(nonatomic, weak, readonly) UIViewController *parentViewController;
  • navigationController

持有该VC的导航栏控制器

@property(nonatomic, readonly, strong) UINavigationController *navigationController;
  • splitViewController

持有该VC的分屏控制器

@property(nonatomic, readonly, strong) UISplitViewController *splitViewController;
  • tabBarController

持有该VC的tabBar控制器

@property(nonatomic, readonly, strong) UITabBarController *tabBarController;

处理内存警告

  • didReceiveMemoryWarning

当应用程序收到内存警告的时候会调用这个方法 ,做相应的解决内存警告的操作

- (void)didReceiveMemoryWarning;

必须调用super实现

协调系统手势

  • preferredScreenEdgesDeferringSystemGestures

协调系统边缘的滑动手势

@property(nonatomic, readonly) UIRectEdge preferredScreenEdgesDeferringSystemGestures;

有时候你的App需要控制从状态栏下拉或者底部栏上滑,这个会跟系统的下拉通知中心手势和上滑控制中心手势冲突。

如果你要优先自己处理手势可以将系统手势延迟。

《解决ios11上 从状态栏下拉或底部栏上滑,跟系统的下拉通知中心手势和上滑控制中心手势冲突》
  • childViewControllerForScreenEdgesDeferringSystemGestures

控制子试图控制器是否允许开发者控制edge protect的开启或是关闭

@property(nonatomic, readonly) UIViewController *childViewControllerForScreenEdgesDeferringSystemGestures;

如果实现了这个方法并且返回值不为空那么子VC的edge protect设置就会遵循父VC的设置,跟随父VC是否延迟执行系统手势。

《关于iPhone X下Home键的隐藏和延迟响应》

管理状态栏

  • childViewControllerForStatusBarStyle

应该使用哪一个VC来确定状态栏的Style

@property(nonatomic, readonly) UIViewController *childViewControllerForStatusBarStyle;

以下解释转自 《iOS状态栏详解》

运用这个函数就可以解决嵌套 UINavigationController 设置样式无效的问题。

解释一下为什么嵌套 UINavigationControllerviewControllerpreferredStatusBarStyle 函数设置无效:

在我们嵌套了 UINavigationController 的时候,我们的

AppDelegate.window.rootViewController

通常是我们创建的 navigationController ,这时首先会调用的是 navigationController 中的 childViewControllerForStatusBarStyle 函数,因为默认返回 nil ,那么接下来就会调用 navigationController 本身的 preferredStatusBarStyle 函数,所以我们在 viewController 中通过 preferredStatusBarStyle 函数设置的状态栏样式就不会被调用发现,所以也就无效了。

所以我们要自己创建一个继承于 UINavigationcontroller

NavigationController ,在这个子类中重写

childViewControllerForStatusBarStyle 函数

- (UIViewController *)childViewControllerForStatusBarStyle{
    return self.topViewController;
}

这样 navigationController 中的 childViewControllerForStatusBarStyle 函数会返回 navigationController 中最上层的 viewController ,那么 viewController 中的 preferredStatusBarStyle 函数的设置就会被系统获知。

  • childViewControllerForStatusBarHidden

应该使用哪一个VC来确定状态栏的显示/隐藏

@property(nonatomic, readonly) UIViewController *childViewControllerForStatusBarHidden;

函数的使用原理同上,不再赘述。

  • preferredStatusBarStyle

状态栏样式

@property(nonatomic, readonly) UIStatusBarStyle preferredStatusBarStyle;

UIStatusBarStyle 是一个枚举类型

typedef NS_ENUM(NSInteger, UIStatusBarStyle) {
//默认样式,黑字透明状态栏,适合用于背景色为亮色的页面
    UIStatusBarStyleDefault                                     = 0, // Dark content, for use on light backgrounds
//白字透明状态栏,适合用于背景色为暗色的页面
    UIStatusBarStyleLightContent     NS_ENUM_AVAILABLE_IOS(7_0) = 1, // Light content, for use on dark backgrounds
    
// iOS7.0以前黑底白字,iOS7以后跟UIStatusBarStyleLightContent效果一样
    UIStatusBarStyleBlackTranslucent NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 1,
// iOS7.0以前启动页为灰底白字,iOS7以后跟UIStatusBarStyleLightContent效果一样
    UIStatusBarStyleBlackOpaque      NS_ENUM_DEPRECATED_IOS(2_0, 7_0, "Use UIStatusBarStyleLightContent") = 2,
} __TVOS_PROHIBITED;

使用起来、需要在具体的VC中

- (UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}
  • prefersStatusBarHidden

状态栏的显示/隐藏

@property(nonatomic, readonly) BOOL prefersStatusBarHidden;

使用起来、需要在具体的VC中

- (BOOL)prefersStatusBarHidden{
    return YES;
}
  • modalPresentationCapturesStatusBarAppearance

在非全屏的模态中、获得状态栏控制权

@property(nonatomic, assign) BOOL modalPresentationCapturesStatusBarAppearance;

modalPresentationCapturesStatusBarAppearance 是专门为强迫症患者量身定制的,只需要重写这个属性并返回 true ,你就可以在任何形式的 Model Presentation 中获得对 Status Bar Style 的控制权了。

  • preferredStatusBarUpdateAnimation

状态栏更新时的动画

@property(nonatomic, readonly) UIStatusBarAnimation preferredStatusBarUpdateAnimation;

重写此方法设置状态栏更新时候的动画

  • setNeedsStatusBarAppearanceUpdate

准备更新状态栏

- (void)setNeedsStatusBarAppearanceUpdate;

当你需要更新状态栏时、调用他。支持动画渐变

配置导航入口

  • navigationItem

分栏控制器按钮

@property(nonatomic, readonly, strong) UINavigationItem *navigationItem;

可以用来设置导航栏上的分栏按钮

UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithImage:[[UIImage imageNamed:@"nav_scan_icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:@selector(rightItemAction)];
    self.navigationItem.rightBarButtonItem = rightItem;

UINavigationItem 的唯一实例、通过懒加载的方式生产。

  • hidesBottomBarWhenPushed

在VC展示时、下方Tabbar是否隐藏

@property(nonatomic) BOOL hidesBottomBarWhenPushed;

通常都是在BaseViewController里设置成YES了。

  • toolbarItems

更改工具栏

- (void)setToolbarItems:(NSArray*)toolbarItems 
               animated:(BOOL)animated;
@property(nonatomic, strong) NSArray*toolbarItems;
  • tabBarItem

Tabbar上的按钮

@property(nonatomic, strong) UITabBarItem *tabBarItem;

编辑行为

  • editing

是否允许用户进行编辑

@property(nonatomic, getter=isEditing) BOOL editing;
  • setEditing:animated:

更新Edit|Done按钮item的外观

- (void)setEditing:(BOOL)editing 
          animated:(BOOL)animated;

当设置 controllerediting 属性,会自动触发 setEditing:animated 属性,这个时候通过 myController editButtonItem 获得的编辑按钮会自动从 edit 变成 Done ,这个通常使用在 navigation Controller

  • editButtonItem

返回Edit|Done按钮。

@property(nonatomic, readonly) UIBarButtonItem *editButtonItem;

比如设置一个右上角按钮为editButton的话代码如下

myViewController.navigationItem.rightBarButtonItem=[myViewController editButtonItem];

参考资料


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK