iOS-UIobject C学习

UIView 和 UIViewController

2016-06-23  本文已影响354人  _凉风_

1. UIViewController

一个控制器,管理一个大界面
负责界面的创建、事件处理等

I. 创建控制器

直接创建

MyViewController *vc = [[MyViewController alloc] init];

通过 xib 创建

MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];

通过 storyboard 创建

// 1. 先加载storyboard文件
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"storyboardName" bundle:nil];

// 2. 初始化storyboard中的控制器
//    2.1 初始化 箭头所指的控制器
MyViewController *vc = [storyboard instantiateInitialViewController];
//    2.2 初始化 标识my对应的控制器
MyViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"my"];

II. 控制器 MyViewController 以及 其 view 的加载过程

  1. 看 loadView 方法是否实现,是,则 使用 loadView 自定义 view,到步骤 7
  2. 若 1 没有实现,看是否从 storyboard 加载,是,则 根据 storyboard 描述创建,到步骤 7
  3. 若 2 没有实现,看是否给 nibName 赋值,是,则 根据 nibName 的值加载 xib 文件,到步骤 7
  4. 若 3 没有实现,看是否存在 MyView.xib 文件「控制器名去掉 Controller」,是,则 加载文件,到步骤 7
  5. 若 4 没有实现,看是否存在 MyViewController.xib 文件,是,则 加载文件,到步骤 7
  6. 若 5 没有实现,创建一个空的 view到步骤 7
  7. 执行 viewDidLoad 函数后,返回一个 view 给控制器
// nibName 为 MyViewController
MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];

// nibName 为 nil
MyViewController *vc = [[MyViewController alloc] init];

注:

III. 控制器 view 的加载方式

2. 多控制器管理

当控制器有多个的时候,建议控制器之间建立层级关系

I. UINavigationController

作用:管理多个控制器
使用步骤

UINavigationController 以的形式保存子控制器


// 栈中的所有子控制器,可以赋值
@property(nonatomic,copy) NSArray *viewControllers;

// 栈中的所有子控制器,不可以赋值
@property(nonatomic,readonly) NSArray *childViewControllers;

// 使用push方法能将某个控制器压入栈
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated;

// 使用add方法同样能将某个控制器压入栈,只不过没有动画
- (void)addChildViewController:(UIViewController *)viewController;

// 使用pop方法可以将栈顶的控制器移除,出栈的控制器会被销毁
- (UIViewController *)popViewControllerAnimated:(BOOL)animated;

// 回到指定的子控制器
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated;

// 回到根控制器(栈底控制器)
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;

控制器的加载步骤


// 1. view加载完毕「一个控制器只调用一次」
- (void)viewDidLoad;

// 2. view即将显示到window上
- (void)viewWillAppear:(BOOL)animated;

// 3. view显示完毕(已经显示到窗口)
- (void)viewDidAppear:(BOOL)animated;

// 4. view即将从window上移除(即将看不见)
- (void)viewWillDisappear:(BOOL)animated;

// 5. view从window上完全移除(完全看不见)
- (void)viewDidDisappear:(BOOL)animated;

// 6. 如果接收到内存警告的时候「应用代理对象先接收到警告,然后传给根控制器内存警告」
- (void)didReceiveMemoryWarning

/* 控制器警告方法执行步骤
    1. 判断控制器内有无 View,有,到 1
    2. 判断控制器内的 View 能否销毁「是否显示在窗口上」,能,到 2
    3. 执行 viewWillUnload
    4. 控制器的 View 被销毁
    5. 执行 viewDidUnload
*/
// --------- 和内存有关的方法 ------------------------------

// 7. view即将销毁的时候调用
- (void)viewWillUnload{
    // 「ARC模式下」控制器内的view对象即将销毁,在它销毁前清空下View中的内容
    self.valueName = nil; // 写nil ARC和MRC 都会清空一下对应的属性
    // 仅在 ARC 下 还可以使用 [self.valueName release];
}

// 8. view销毁完毕的时候调用
- (void)viewDidUnload;

II. UITabBarController

使用步骤

添加控制器

特性

Paste_Image.png

III. Segue

简介:操作界面跳转的 UIStoryBoardSegue对象
属性

// 表示是哪个 Segue 的唯一标识
@property (nonatomic, readonly) NSString *identifier;

// 来源控制器「从哪里开始跳转界面」
@property (nonatomic, readonly) id sourceViewController;

// 目标控制器「跳转到那个界面」
@property (nonatomic, readonly) id destinationViewController;

使用步骤

  1. 在 StoryBoard 上拖线,表明来源控制器和目标控制器
Paste_Image.png

手动拖线

Paste_Image.png
  1. 给拖好的线 Segue 设置一个 唯一标识
Paste_Image.png
  1. 使用perform方法执行对应的Segue
// Segue必须由来源控制器来执行,也就是说,这个perform方法必须由来源控制器来调用
[self performSegueWithIdentifier:@"Segue的唯一标识名" sender:nil];

IV. 补充

1)performSegueWithIdentifier:sender: 方法的完整执行过程

  1. 根据identifier去storyboard中找到对应的线,新建UIStoryboardSegue对象

    • 设置Segue对象的sourceViewController(来源控制器)
    • 新建并且设置Segue对象的destinationViewController(目标控制器)
  2. 调用sourceViewController的下面方法

    • 做一些跳转前的准备工作并且传入创建好的Segue对象
      这个sender是当初 performSegueWithIdentifier:sender:中的sender
      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender;
  3. 调用Segue对象的- (void)perform;方法开始执行界面跳转操作

    • 如果segue的style是push
      取得sourceViewController所在的UINavigationController
      调用UINavigationController的push方法将destinationViewController压入栈中,完成跳转
    • 如果segue的style是modal
      调用sourceViewController的presentViewController方法将destinationViewController展示出来

2)Modal 简介

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

3. UIView

I. UIView 的显示步骤

  1. view 内部的 Layer 会准备好一个 CGContextRef「图层类型上下文」
  2. 调用 delegate「这里就是 UIView」的 drawLayer:inContext: 方法
    传入已经准备好的 CGContextRef 对象
  3. view 在 drawLayer:inContext: 方法中又会调用自己的 drawRect: 方法
  4. view 就可以在 drawRect: 方法中实现绘图代码, 所有东西最终都绘制到 view.layer 上面
  5. 系统再将 view.layer 的内容拷贝到屏幕, 于是完成了 view 的显示

II. 系统自动调用的方法「留给子类去实现」

// 控件的frame发生改变的时候就会调用
// 一般在这里重写布局子控件的位置和尺寸
// 重写了这个写方法后,一定调用 [super layoutSubviews];
- (void)layoutSubviews;
- (void)didAddSubview:(UIView *)subview;
- (void)willRemoveSubview:(UIView *)subview;
- (void)willMoveToSuperview:(UIView *)newSuperview;
- (void)didMoveToSuperview;
- (void)willMoveToWindow:(UIWindow *)newWindow;
- (void)didMoveToWindow;

III. 响应接口

@interface UIView : UIResponder<NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem>

// 能否和用户进行交互「默认 能」
@property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;

// 控件的一个标记:父控件可以通过tag找到对应的子控件
@property(nonatomic) NSInteger tag;

// 图层:可以用来设置 圆角\阴影 效果
@property(nonatomic,readonly,retain) CALayer  *layer;

// 通过一个frame来初始化一个UI控件
- (id)initWithFrame:(CGRect)frame;

@end

IV. 几何图形接口

@interface UIView(UIViewGeometry)

// 位置和尺寸:以「自己」的左上角为坐标原点(0, 0)
@property(nonatomic) CGRect bounds;

// 位置和尺寸:以「父控件」的左上角为坐标原点(0, 0)
@property(nonatomic) CGRect frame;

// 中点:以「父控件」的左上角为坐标原点(0, 0)
@property(nonatomic) CGPoint center;

// 形变属性「平移\缩放\旋转」
@property(nonatomic) CGAffineTransform transform;

// 是否支持多点触摸「默认 不支持」
@property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled;

@end

V. View 结构接口

@interface UIView(UIViewHierarchy)

// 父控件
@property(nonatomic,readonly) UIView *superview;

// 子控件(新添加的控件默认都在subviews数组的后面, 新添加的控件默认都显示在最上面\最顶部)
@property(nonatomic,readonly,copy) NSArray *subviews;

// 获得当前控件所在的window
@property(nonatomic,readonly) UIWindow *window;

// 从父控件中移除一个控件
- (void)removeFromSuperview;

// 添加一个子控件(可以将子控件插入到subviews数组中index这个位置)
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;

// 交换subviews数组中所存放子控件的位置
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;

// 添加一个子控件(新添加的控件默认都在subviews数组的后面, 新添加的控件默认都显示在最上面\最顶部)
- (void)addSubview:(UIView *)view;

// 添加一个子控件view(被挡在siblingSubview的下面)
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;

// 添加一个子控件view(盖在siblingSubview的上面)
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;

// 将某个子控件拉到最上面(最顶部)来显示
- (void)bringSubviewToFront:(UIView *)view;

// 将某个子控件拉到最下面(最底部)来显示
- (void)sendSubviewToBack:(UIView *)view;

// 判断view的子控件 或者 子控件的子控件 是否为view的后代,默认自己也是自己的后代
- (BOOL)isDescendantOfView:(UIView *)view;  // returns YES for self.

// 通过tag获得对应的子控件
// 也可以或者子控件的子控件,循环遍历的方式,也遍历自己,性能不好
- (UIView *)viewWithTag:(NSInteger)tag;

@end

VI. 渲染接口

@interface UIView(UIViewRendering)

// 超出控件边框范围的内容是否都剪掉
@property(nonatomic) BOOL clipsToBounds;

// 背景色「默认 nil」
@property(nonatomic,copy) UIColor *backgroundColor;

// 透明度「0.0~1.0,默认 1.0」
@property(nonatomic) CGFloat alpha;

// 是否不透明,是 则 不透明「默认 不透明」
@property(nonatomic,getter=isOpaque) BOOL opaque;

// 是否隐藏,是 则 隐藏
@property(nonatomic,getter=isHidden) BOOL hidden;

// 内容模式(居中/填充/拉伸)「默认 填充,UIViewContentModeScaleToFill」
@property(nonatomic) UIViewContentMode contentMode;

@end

VII. Block 动画接口

@interface UIView(UIViewAnimationWithBlocks)

+ (void)animateWithDuration:(NSTimeInterval)duration
                      delay:(NSTimeInterval)delay
                    options:(UIViewAnimationOptions)options
                 animations:(void (^)(void))animations
                 completion:(void (^)(BOOL finished))completion;

+ (void)animateWithDuration:(NSTimeInterval)duration
                 animations:(void (^)(void))animations
                 completion:(void (^)(BOOL finished))completion;

+ (void)animateWithDuration:(NSTimeInterval)duration
                 animations:(void (^)(void))animations;

+ (void)animateWithDuration:(NSTimeInterval)duration
                      delay:(NSTimeInterval)delay
     usingSpringWithDamping:(CGFloat)dampingRatio
      initialSpringVelocity:(CGFloat)velocity
                    options:(UIViewAnimationOptions)options
                 animations:(void (^)(void))animations
                 completion:(void (^)(BOOL finished))completion;
@end
上一篇下一篇

猜你喜欢

热点阅读