【IOS开发—视图】

一、UIWindow对象

每一个app都有一个UIWindow对象,它像一个容器一样,用来包含应用中的所有视图,应用会在启动时创建并设置UIWindow对象。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    //添加ViewController
    ViewController *controller = [[ViewController alloc] init];
        ……………………
    self.window.rootViewController = controller;
    [self.window setBackgroundColor:[UIColor whiteColor]];

    [self.window makeKeyAndVisible];

    return YES;
}

加入窗口的视图会成为窗口的子视图,子视图还可以包含自己的子视图,这是一个类似Android View的一个层级关系。

二、UIView

1)每一个UIView都有一个layer属性,对应一个CALayer类的对象。然后所有的Layer组合成一幅图像,绘制在屏幕上。

2)UIView的frame属性保存的是视图的大小及相对父视图的位置,用CGRect来描述(它是一个结构体 struct)

3)frame和bounds的区别:frame用于确定与其他视图层次结构中其他视图的相对位置;而bounds用于确定绘制区域,避免绘制到图层边界外面。

三、Core Graphics

  Core Graphics是一套提供2D绘图功能的C语言的API,Core Graphics中最重要的“对象”是图形上下文(graphics context),图形上下文是CGContextRef的“对象”,负责存储绘图状态(例如画笔颜色和线条粗细)和绘图内容所处的内存空间。

- (void)drawRect:(CGRect)rect
{

    //获取绘图的Context
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    //保存当前的上下文
    CGContextSaveGState(currentContext);

    //目前只能通过 Core Graphics设置阴影
    CGContextSetShadow(currentContext, CGSizeMake(4, 7), 3);
    //这里绘制的图形有阴影效果

    //恢复之前的上下文
    CGContextRestoreGState(currentContext);

    //这里绘制的图像没有阴影效果。
}

其中图形的上下文context 在drawRect之前就已经创建了。

四、用UIBezierPath画一个三角形

    //定义渐变的path
    UIBezierPath *myPath = [[UIBezierPath alloc] init];
    //用myPath化一个三角形
    [myPath moveToPoint:CGPointMake(160, 142)];
    [myPath addLineToPoint:CGPointMake(260, 446)];
    [myPath addLineToPoint:CGPointMake(60, 446)];
    [myPath addLineToPoint:CGPointMake(160, 142)];
    [myPath setLineWidth:10];
    //设置填充颜色
    [[UIColor redColor]setFill];
    [[UIColor redColor] setStroke];

    [myPath fill];
    [myPath stroke];

注意画三角形的方式:寻找一个点,然后以这一点为起点画三条线。

 五、运行循环和重绘视图

  IOS应用启动时会开始一个运行循环(run loop),循环的工作是为了监听事件,比如:触摸事件。当在View中监听到对应的事件时,程序会首先执行对应事件的处理逻辑(比如点击屏幕时,改变屏幕某个元素的背景色),直到这些逻辑都执行完,才将控制权交给运行循环。

  运行循环在得到控制权时会首先检查是否有等待重绘的View(这需要View手动去设置setNeedsDisplay),然后会向需要重绘的视图发送drawRect消息,从而将新的视图显示在屏幕上。重绘肯定是比较耗时的,IOS做了两方面的优化:

1)不重绘那些内容没有发生变化的视图

2)在每次事件处理周期中只发生一次drawRect消息,也就是说无论事件周期里视图发生多少变化,只会在最后执行一次drawRect。

  另外setNeedsDisplayInRect是为了指定只重绘某一区域。通常情况下我们并不指定区域。

PS:碰到一个问题,在UIView的子类中,监听触摸的事件并没有执行。

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

然后只是在APPDelegate中修改了代码的顺序,问题就解决了,我也没想明白为什么会这样:

    self.window.rootViewController = controller;
    [self.window setBackgroundColor:[UIColor whiteColor]];

    [self.window makeKeyAndVisible];
    [self.window addSubview:BNRView];

就是将 [self.window addSubview:BNRView]放到 [self.window makeKeyAndVisible]后面。

 六、UIScrollView

  UIScrollView有几个属性和方法注意下:

1)contentSize 决定了UIScrollView能显示多大面积的View(打个比方,UIScrollView像照相机一样,而contentSize就决定了能显示多达面积)。

2)pagingEnable 的作用是比如有两页数据,在滑动到第二页时,松开手指能自动定位到第二页。这种效果在移动端是很常见的。原理是:UIScrollView会根据其bounds的尺寸,将contentSize分割为尺寸相同的多个区域,拖动结束后,UIScrollView会自动滚动并只显示其中的一个区域。

下面的代码是在一个UIScrollView中有两个大小一样的视图:

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

    //添加ViewController
    ViewController *controller = [[ViewController alloc] init];

    //创建两个CGRect结构作为UIScrollView和BNRHypnosisView对象的frame
    CGRect screenRect = self.window.bounds;
    CGRect bigRect = screenRect;
//    bigRect.size.height *=2.0;
    bigRect.size.width  *=2.0;

    //创建一个UIScrollView对象,将其尺寸设置为窗口大小
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:screenRect];
    [scrollView setPagingEnabled:YES];

    //创建一个超大尺寸的BNRHypnosisView(修改创建一个与屏幕等宽的View)
    BNRHyponsisViewTwo *hyponsisView = [[BNRHyponsisViewTwo alloc] initWithFrame:screenRect];
    [scrollView addSubview:hyponsisView];

    screenRect.origin.x += screenRect.size.width;
    BNRHyponsisViewTwo *antherView = [[BNRHyponsisViewTwo alloc] initWithFrame:screenRect];
    [scrollView addSubview:antherView];

    //设置scrollView的取景范围
    scrollView.contentSize = bigRect.size;

    self.window.rootViewController = controller;
    [self.window setBackgroundColor:[UIColor whiteColor]];

    [self.window makeKeyAndVisible];
//    [self.window addSubview:BNRView];
    [self.window addSubview:scrollView];
时间: 11-17

【IOS开发—视图】的相关文章

IOS开发—视图控制器左边缘右滑pop出栈

IOS视图控制器左边缘右滑pop出栈 IOS7.0之后,苹果优化了一个小功能,就是对于UINavagationController堆栈里的UIViewController,只要轻轻在视图控制器的左边缘右滑一下,该视图控制器就会pop出栈(前提当然是对于非根视图控制器而言).实现方法很简单,一句话搞定: self.navigationController.interactivePopGestureRecognizer.enabled = YES; 事实上对于一个视图控制器而言,该属性的默认值即为Y

IOS开发--视图控制器和基础视图

一.视图控制器 UIViewController的介绍: UIViewController即视图控制器,它在MVC(Model View Controller)模式中充当控制者的角色,它负责控制视图的显示,以及响应用户在该视图中所有可能的动作.使用视图控制器,我们可以很方便的管理视图及其子视图. UIViewController的生命周期: 运行APP--载入视图loadView--调用viewDidLoad方法--调用viewWillAppear方法--调用viewDidAppear方法--正

【IOS开发—视图控制器】

一.UIViewController 视图控制器是UIViewController类或者其子类对象,每个视图控制器都负责管理一个视图层次结构.在UIViewController中有一个重要的UIView属性, 这个view就是这个视图层的根视图,当程序将view作为子视图加入窗口时,也会加入UIViewController对象所管理的整个视图层次结构. 视图控制器只有在将某个视图显示在屏幕上时,相应的视图控制器才会创建其视图,这种延迟加载视图的做法能提高内存的使用效率.视图控制器创建视图的方式有

ios 开发视图界面动态渲染

#import "MyView.h" IB_DESIGNABLE @interface MyView () @property (nonatomic, strong) IBInspectable UIColor * borderColor; @property (nonatomic, assign) IBInspectable CGFloat borderWidth; @property (nonatomic, assign) IBInspectable CGFloat cornerR

iOS开发——代码生成TabBar与视图切换详解

我在之前多篇博客中讲解了在不使用storyboard而使用nib文件的情况下,使用代码生成导航栏并进行跳转,具体可以参考<iOS开发--界面跳转与返回及视图类型详解><iOS纯代码实现界面建立.跳转.导航栏(无storyboard.无nib)(Objective-C)>.今天我来讲解下在使用nib搭建界面的情况下,用代码生成TabBar,并进行界面之间的跳转.代码示例已经上传至:https://github.com/chenyufeng1991/TabBarTest   . (1)

iOS开发——代码生成TabBar与视图切换具体解释

我在之前多篇博客中解说了在不使用storyboard而使用nib文件的情况下.使用代码生成导航栏并进行跳转,具体能够參考<iOS开发--界面跳转与返回及视图类型具体解释><iOS纯代码实现界面建立.跳转.导航栏(无storyboard.无nib)(Objective-C)>. 今天我来解说下在使用nib搭建界面的情况下,用代码生成TabBar,并进行界面之间的跳转.代码演示样例已经上传至:https://github.com/chenyufeng1991/TabBarTest  

[转]iOS开发之视图控制器(UIViewController)

视图控制器应该在MVC设计模式中扮演控制层(C)的角色,UIViewController的职责对内管理与之关联的View,对外跟其他UIViewController通信和协调.一个视图控制器管理一个视图(它可以有子视图),其view属性指向它所管理的视图.UIViewController类可以有子类,可以使用一个系统的UIViewController子类或者直接自己创建一个UIViewController的子类. 使用代码创建控制器和视图. 开始创建一个基于窗口的Empty Applicatio

【iOS开发-26】利用协议代理实现导航控制器UINavigationController视图之间的正向传值和反向传值

实验说明 (1)正向传值:比如A类里地值要传给B类用,就是我们先在A类中声明一个B类对象(当然B类头文件要import过来),然后把A类中得某个值传递给B类中得某个值(所以需要在B类中先准备一个变量来接受,就是用@property和@synthesize整个变量即可). (2)反向传值:比如需要把B类中的值传递给A类用.我们先在B类中写一个协议,协议里面有一个可以带参数的方法,这个参数就是我们要传递的值(这个协议也可以单独写,不一定写在B类中),然后B类遵循这个协议后,利用这个协议创建一个委托变

iOS开发:使用Tab Bar切换视图

iOS开发:使用Tab Bar切换视图 上一篇文章提到了多视图程序中各个视图之间的切换,用的Tool Bar,说白了还是根据触发事件使用代码改变Root View Controller中的Content View.这次,我们还是讲一讲切换视图,不过这次使用的是Tab Bar. 这次要写的程序运行起来的效果是这样的:底部有几个图标,每个图标对应一个视图.每点击一个图标,对应的视图就会打开.如下图,就是我们做好的程序效果:    每个Tab Bar有一个对应颜色的视图. 为了搞清使用Tab Bar切