• 视图,表示屏幕上的一块矩形区域,同时处理该区域的绘制和触屏事件。
  • 一个视图也可以作为其他视图的父视图,同时决定着这些子视图的位置和大小.
  • UIView类做了大量的工作去管理这些内部视图的关系。
  • 视图同时也是App中MVC的View部分
  • iPhone的视图以左上角为原点
  • 每个View的frame所使用的坐标系以它的父视图的左上角为坐
    关函数
    • 视图结构和相
    1
    2
    3
    CGPoint Point = CGPointMake(x,y);//设置
    CGSize size = CGSizeMake(width,height);//大小
    CGRect rect = CGRectMake(x,y,width,height);//位置和大小

Frame和Bounds

  • Frame以其父视图为起点,得出它自己的位置信息
  • Bounds以iOS系统的坐标原点为起点,坐标是(0,0)
  • Center表示视图中心所在的位置,设置此属性可改变视图的位置
    • 默认情况下,视图边框并不会被父视图的边框裁剪。如果需要裁剪,将其clipsToBounds属性设置为YES.

创建UIView

  • 创建UI有两种方式,xib文件和代码创建
1
2
3
4
5
//通过xib方式来创建视图对象
NSBundle *bundle = [NSBundle mainBundle];
NSArray *arr = [bundle loadNibNamed:@"myView" owner:self
options:nil];
UIView *myView = [arr objectAtIndex:0];
1
2
3
//代码创建视图对象
CGRect viewRect = CGRectMake(0,0,100,100);
UIView *myView =[[UIView alloc] initWithFrame:viewRect];

视图的层次结构

  • UIView层次结构可以理解为“视图树”————view hierarychy
  • 一个视图就是一个容器,当一个视图包含其他的视图的时候,两个视图之间就建立了一个父子关系,被包含的视图被称为“姿势图(subView)”,包含的视图称为“父视图(superView)”
  • 从视觉上看,子视图会覆盖父视图的内容,设置透明属性可以看到父视图的内容。
  • 每个父视图都有一个有序的数组存储着它的子视图,存储的顺序就会影响到每个子视图的显示效果,后加的视图会覆盖之前的视图。
  • 一个视图可以嵌入多个subView,但是只能有一个superView。
    • 视图的常用方法
    1
    2
    3
    4
    5
    6
    7
    8
    addSubView:                     // 添加子视图
    insertSubview:atIndex: // 视图插入到指定索引位置
    insertSubview:ahoveSubview: // 视图插入指定视图之上
    insertSubview:belowSubview: // 视图插入指定视图之下
    bringSubviewToFront: // 把视图移动到最顶层
    sendSubviewToBack: // 把视图移动到最底层
    exchangeSubViewAtIndex:withSubviewAtIndex://把两个索引对应的视图调换位置
    removeFromSuperview: // 把视图从父视图中移除

查找视图

  • UIView类中有一个tag属性,通过这个属性可以标志一个视图对象(整数)
  • 获取的方法,viewWithTag:方法来检索标志过的子视图
    1
    2
    3
    4
    UIView *myView = [[UIView alloc] initWithFrame:CGRectmake(0,0,100,100)];
    myView.tag = 100;
    // 通过tag查找view
    UIView *myView = [self.view vieWithTag:100];

UIView的常用属性

  • alpha // 透明度
  • backgroundColor // 背景颜色
  • subViews // 子视图集合
  • hidden // 是否隐藏
  • tag // 标签值
  • superview // 父视图
  • mulitpleTouchEnaled // 是否开启多点触摸
  • userInteractionEnabled // 是否响应触摸事件

坐标系统变换

  • 坐标变换通过transform属性来改变
    • CGAffineTransformScale 对视图比例缩放
    • CGAffineTransformRotae 对视图做变焦旋转
    • CGAffineTransformTranslate 对视图相对原位置做平移
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
        CGAffineTransform transform = rootView.transform;
    rootView.transform = CGAffineTransformScale(transform,0.5,0.5);
    rootView.transform = CGAffineTransformRotae(transform,0.33);
    CGAffineTransformScale(transform,0.5,0.5);
    rootView.transform = CGAffineTransformTranslate(transform,100,100);

    ## 视图的内容模式
    - 视图的contentMode属性决定了边界变化和缩放操作
    ```Objective-c
    UIImageView *imgeView1 = [[UIImageView alloc] initWithFrame:CFRectMake(320/2-200/2,30,200,200)];
    imgeView1.imge = [UIImage imageNamed:@"01"];
    imgeView1.backgroundColor = [UIColor redColor];
    imgeView1.contentMode = UIViewContentModeScaleAspectFit;
    [self.window addSubview:imgeView1];
    [imView1 release];

    UIImageView *imgeView2 = [[UIImageView alloc] initWithFrame:CFRectMake(320/2-200/2,240,200,200)];
    imgeView2.backgroundColor = [UIColor yelloColor];
    imgeView2.contentMode = UIViewContentModeBottom;
    [self.window addSubview:imgeView2];
    [imView2 release];

UIView属性的动画

  • UIView类的很多属性都被设计为动画,动画的属性是指当属性从一个值变为另一个值的时候,可以半自动地支持动画,你仍然必须告诉UIKit希望执行什么类型的动画,但是动画一旦开始,Core Animation就会全权负责。UIView对象中支持动画的属性有如下几个:
    • frame - 动画的改变视图的尺寸和位置
    • bounds - 动画的改变视图的尺寸
    • center - 动画的改变视图的位置
    • transform - 动画的翻转或者缩放视x图
    • alpha - 动画的改变视图的透明度
    • backgroundColor - 改变视图的背景色
    • contentStetch - 改变视图内容如何拉伸

配置动画委托

- 可以为动画分配一个委托,并通过该委托接受动画开始和结束的消息。当需要在动画开始前和动画结束后极力执行其他任务时,可能就需要设置委托。
- 通过UIView调用setAnmationDelegate:方法来设置委托,并通过setAnimationWillStartSelector:和setAnimationDidStopSelector:方法来指定接受消息的选择器方法。消息处理方法形式如下:
`(void)animationWillStart:(NSString *)animationID context:(void *)context;`
`(void)animationDidStop:(NSString *)animationID finished context:(void *)context;`
上面的两个方法的animationID和context参数和动画块开始时传给`beginAnimations:context:`方法的参数相同
    + animationID - 应用程序提供的字符串,用于标识一个动画块中的动画
    + context - 应用程序提供的对象,用于向委托对象传递额外的信息
    
setAnimationDidStopSelector:选择器方法还有一个参数——即一个布尔值。如果动画顺利完成,没有被其他动画取消或停止,则该值为YES。
### 配置动画的参数
- 用`setAnimationStartDateS`方法来设置动画在`commitAnimations:`方法返回之后的发生日期。
- 用`setAnimationDelay:`方法来设置实际发生动画和`commitAnimations:`方法返回的时间点之间的间隔
- 用`setAnimationDuration:`方法来设置动画的持续秒数
- 用`setAnimationCurve:`方法来设置动画过程的相对速度,比如动画可能在启动阶段逐渐加速、而在结束阶段逐渐减少,或者这个过程都保持相同的速度
- 用`setAnimationRepeatCount:`方法来设置动画的重复次数
- 用`setAnimationRepeatAutoreverses:`方法来指定动画在到达目标值时是否自动反向播放。可是结合使用这个方法和`setAnimationRepeatCount:`方法,使各个属性在初始值和目标值之间平滑切换一段时间。
- 缺省情况下,所有支持动画的属性在动画块中发生的变化都会形成动画。如果希望让动画块中发生的某些变化不产生动画效果,可以通过`setAnimationsEnableed:`方法来暂时禁止动画,在完成修改后才重新激活动画,在调用`setAnimationsEnabled:`方法并传入NO值之后,所有的改变都不会产生动画效果,指定用YES值再次调用这个方法或者提交这个动画块是,动画才会恢复,可以用`areAnimationsEnable:`方法来确定当前是否激活动画。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-(void)animationAlpha
{
[UIView beginAnimations:nil context:NULL];// 需要设置代理时
[UIView setAnimationDuration:1];// 动画的持续时间
[UIview setAnimationDelay:1];// 动画延迟时间
view2.apleha = 0.0;
[UIView commitAnimations];// 标记着动画块的结束
}
-(void)animationFrame
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:5];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];// 动画相对速度,开始和结束的时候慢,中间快
view.center = CGPointMake(0,0);
[UIView commitAnimations];
}

UIViewController

  • 视图控制器是数据和视图之间的桥梁,视图供职器提供了一个基本的框架来构建应用程序。
  • UIViewController是所有视图控制器的父类
  • iOS提供了许多内置的视图控制器,以支持标准的用户界面部分,比如导航控制器UINavigationController,标签栏控制器UITabBarController,表视图控制器UITableViewController

视图控制器与视图的关系

  • 视图控制器是传统Modle-View-Controller(MVC)设计模式中————控制器对象
  • 视图控制器提供了许多控制器的基本功能
  • 对于某些功能,基类提供了解决方案的一部分,其他的自定义的功能由视图控制器的子类去实现,比如:用户选择设备,可以由子类去控制是否旋转
  • 视图控制器负责创建和管理一组视图,它本身提供一个视图,称为该试图控制器的根视图,协调管理数据的视图之间的交互
    • UIScreen对象时链接物理屏幕的标示
    • UIWindow为UIScreen对象提供画布
    • 一组UIView对象就可以显示内容
    • 每个视图控制器管理和控制一系列的视图
    • 永远不要把UIView添加到UIWindow上,二是添加一个UIViewController

视图控制器(UIViewController)的创建

1
2
3
4
5
6
7
8
// 代码创建
UIViewController *mainViewController = [[UIViewCtroller alloc] init];
mainViewController.view.backgroundColor = [UIColor redColor];
self.window.rootViewController = mainViewCtroller;
// nib创建
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"view" bundle:nil];
self.window.rootViewController = rootViewController;

UIViewController生命周期

1
2
3
4
5
6
7
-(void)loadView
{
// 调用父类来创建view
// 从nib、storybord加载View,否则创建一个empty view
// 创建一个自定义的视图,覆盖即可
}
-(void)view

加载过程

  • 首先去访问view属性
  • 如果存在view,判断之间加载。否则,则UIViewCtroller调用loadView方法
    • loadView方法执行如下操作
      • 如果覆盖了该方法,则必须创建View给UIViewCtroller的View属性
      • 如果没有覆盖该方法,UIViewControlller会调用父类的方法

各个方法执行顺序

        - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
        - (void)loadView
        - (void)viewDidLoad
        - (void)viewWillAppear:(BOOL)animated
        - (void)viewDidAppear:(BOOL)animated
        - (void)viewWillDisappear:(BOOL)animated
        - (void)viewDidDisappear:(BOOL)animated

视图卸载

  • iOS6之前使用viewDidUnload:方法来释放对象的引用
  • iOS6之后使用didRecevelMemoryWarning内存紧张的时候调用
  1. viewWillDisappear 视图将被从屏幕上移除之前执行
  2. viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图
  3. dealloc 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放

试图控制器的响应链

  • 事件传递流程
    当前触发的事件->视图控制器的跟视图->视图控制器->窗口->UIApplication对象->不处理

模态视图

  • 模态视图不是特定的某个类,而是通过视图控制器的pressntModalViewController:方法弹出的视图称为模态视图
  • 模态视图出现的场景一般是临时弹出的窗口,譬如:登入窗口
  • 模态视图弹出时通过modalTransitionStyle属性设置不同的动画效果
  • 调用dismissModalViewControllerAnimated:方法关闭窗口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-(void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor purpleColor];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundeRect];
button.frame = CGRectMake(320/2 - 140/2,80,140,40);
[button setTitle:@"Present" forState:UIControlStateNormal];
[button addTarget:self action:@selector[presentModalVc] forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
}
-(void)presentModalVC
{
ModalViewController *modalVc = [[ModalViewController alloc] init];
// 动画效果
modalVc.modalTranstionSyle = UIModalTransitionStylePatialCurl;
if([[UIDevice currentDevice].systemVersion floatValue] < 6.0){
[self.presentModalViewController:modalVc animated:YES];
}else{
[self.presentModalViewController:modalVc animated:YES completion:^{
NSLog(@"call back");
}];
[modalVC relese];
}
}
1
2
3
4
5
6
7
8
//ModalViewController.m
-(void)dismiss
{
// 将模态视图关闭
[self dismissViewControllerAnimated:YES completion:^{
NSLog(@"dismiss")];
}];
}

支持多个方向

  • iOS设备中的加速计可以确定设备的当前方向。默认情况下,一个应用支持纵向和横向。当设备方向改变时,系统会发送UIDiviceOrientationDidChangeNotfication通知,默认情况下UIKit框架监听这个通知,并自定义更新这个方向。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
-(void)viewDidLoad
{
// ...
// 采用通知获取屏幕方向切换
[[UINotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientation:)name:UIDeviceOrientationDidChangeNotifitation object:nil];
}
-(void)deviceOrientation:(NSNotification *)notification
{
UIDevice *device = (UIDevice *)[notification object];
NSLog(@"device:%d",device.orientation);
}
-(BOOL)shoudlAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
return NO; //NO为不支持
// return (toInterfaceOrientation != UIterfaceOrientationLandscapeLeft); // 不支持一个方向
}
# pragma mark - Orientation iOS 3.0_5.0
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrienttation)toInterfaceOrientation
{
return NO;
}
# pragma mark - Orientation iOS 6.0
-(BOOL)shouldAutorotate
{
return YES;
}
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
NSLog(@"duration:%f",duration);
UIView* button = [self.view viewWithTag:101];
if(toInterfaceOrientation == UIInterfaceOrientationPortrait){
button.frame = CGRectMake(320/2-140/2,80,140,40);
}else{
button.frame = CGRectMake(480/2-140/2,80,140,40);
}
}

  • UIView是视图的基类
  • UIViewController视图控制器的基类
  • UIResponder表示一个可以接受触摸屏上触摸事件的对象
  • UIWin(窗口)是视图的一个子类,窗口的主要功能:1、提供一个区域来显示视图,2、将事件(event)分发给视图。
1
2
3
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen] bounds];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];

UIScreen

- UIScreen对象可以充当iOS设备物理屏幕的替代者,通过`[[UIScreen mainScreen] bounds]`可以获得设备的屏幕大小

UIWindow

- 通过UIApplication获取当前keyWindow,keyWindow是用来管理键盘以及触摸类的消息,并且只能有一个window是keyWindow.
- UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
- 每个UIWindow对象配置windowLevel属性,大部分时候不应该去改变windowL.
- UIWindow有3个级别,对应了3种显示优先级。通过windowLevel设置,优先级为:UIWindowLevel > UIWindowLevelStatusBar > UIWindowLevelNormal
1
2
3
4
5
6
7
8
9
10
11
12
//didFinishLauchingWithOptions
self.windonw = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScrren] bounds]];
self.window.backgrondColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
NSLog(@"self.window level: %@",self.windonw.level);

UIButton *startButton = [UIButton buttonWithType:UIButtonTypeRounedRect];
startButton.frame = CCRectMake(320/2-120/2,180,120,35);
[startButton setTile:@"警告" action:@selector(alertUser) forControlEvents:UIControlEventTouchUpInside];
[self.window addSubview:startButton];

return YES;
1
2
3
4
5
6
7
8
9
10
11
// alerUser
-(void)alertUser
{
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle:@"提示"
message:@"警告框是alert Level级别的"
delegate:nil
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alertView show];
}