一、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(, ), );
//这里绘制的图形有阴影效果 //恢复之前的上下文
CGContextRestoreGState(currentContext); //这里绘制的图像没有阴影效果。
}

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

四、用UIBezierPath画一个三角形

    //定义渐变的path
UIBezierPath *myPath = [[UIBezierPath alloc] init];
//用myPath化一个三角形
[myPath moveToPoint:CGPointMake(, )];
[myPath addLineToPoint:CGPointMake(, )];
[myPath addLineToPoint:CGPointMake(, )];
[myPath addLineToPoint:CGPointMake(, )];
[myPath setLineWidth:];
//设置填充颜色
[[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];

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

  1. ios开发----视图的生命周期

    熟悉web开发的朋友可能对页面page的生命周期有一定的了解和认识,正如web开发中的页面生命周期一样,移动客户端开发也有它自己的生命周期.下文将说明ios开发中视图的生命周期既运行顺序. 在ios视 ...

  2. 玩转iOS开发 - 视图控制器生命周期

    视图控制器生命周期

  3. 【IOS开发—视图控制器】

    一.UIViewController 视图控制器是UIViewController类或者其子类对象,每个视图控制器都负责管理一个视图层次结构.在UIViewController中有一个重要的UIVie ...

  4. ios 开发视图界面动态渲染

    #import "MyView.h" IB_DESIGNABLE @interface MyView () @property (nonatomic, strong) IBInsp ...

  5. iOS开发系列--视图切换

    概述 在iOS开发中视图的切换是很频繁的,独立的视图应用在实际开发过程中并不常见,除非你的应用足够简单.在iOS开发中常用的视图切换有三种,今天我们将一一介绍: UITabBarController ...

  6. iOS开发之多表视图滑动切换示例(仿"头条"客户端)---优化篇

    前几天发布了一篇iOS开发之多表视图滑动切换示例(仿"头条"客户端)的博客,之所以写这篇博客,是因为一位iOS初学者提了一个问题,简单的写了个demo做了个示范,让其在基础上做扩展 ...

  7. iOS开发之表视图爱上CoreData

    在接触到CoreData时,感觉就是苹果封装的一个ORM.CoreData负责在Model的实体和sqllite建立关联,数据模型的实体类就相当于Java中的JavaBean, 而CoreData的功 ...

  8. IOS开发之视图和视图控制器

    视图(View), 视图控制器(ViewController)是IOS开发UI部分比较重要的东西.在学习视图这一块的东西的时候,感觉和Java Swing中的Panel差不多.在UIKit框架中都有一 ...

  9. iOS开发app启动原理及视图和控制器的函数调用顺序

    main()函数是整个程序的入口,在程序启动之前,系统会调用exec()函数.在Unix中exec和system的不同在于,system是用shell来调用程序,相当于fork+exec+waitpi ...

随机推荐

  1. orm加强版

    目录 十三式 2式(针对外键查询优化) select_related和prefetch_related prefetch_related 查询返回值类型 不等式查询 关键字查询 时间查询 跨表查询 组 ...

  2. 04-02 AdaBoost算法

    目录 AdaBoost算法 一.AdaBoost算法学习目标 二.AdaBoost算法详解 2.1 Boosting算法回顾 2.2 AdaBoost算法 2.3 AdaBoost算法目标函数优化 三 ...

  3. 04-10 Bagging和随机森林

    目录 Bagging算法和随机森林 一.Bagging算法和随机森林学习目标 二.Bagging算法原理回顾 三.Bagging算法流程 3.1 输入 3.2 输出 3.3 流程 四.随机森林详解 4 ...

  4. bugku 程序员本地网站

    提示从本地访问,怎样让服务器认为你是从本地进行访问的: 使用burp抓包并在包中进行修改加入X-Forwarded-For: 127.0.0.1 X-Forwarded-For: 简称XFF头,它代表 ...

  5. 像艺术家一样思考 Think Like an Artist

    艺术家是如何获得灵感,如何找到自己的独特风格和主题的? 艺术家在绘画.写作.表演或歌唱前不会去征求谁的允许,而是随心而行 要想在数字时代获得满足感,我们需要变得有创造性 1.艺术家富有事业心 艺术家是 ...

  6. python selenium下拉框定位

    一.前言 总结一下python+selenium select下拉选择框定位处理的两种方式,以备后续使用时查询: 二.直接定位(XPath) 使用Firebug找到需要定位到的元素,直接右键复制XPa ...

  7. (19)ASP.NET Core EF创建模型(包含属性和排除属性、主键、生成的值)

    1.什么是Fluent API? EF中内嵌的约定将POCO类映射到表.但是,有时您无法或不想遵守这些约定,需要将实体映射到约定指示外的其他对象,所以Fluent API和注解都是一种方法,这两种方法 ...

  8. CVE-2019-0708(非蓝屏poc)远程桌面代码执行漏洞复现

    玩了几天 刚回成都  玩电脑复现一下~ 内核漏洞原理暂时 没看懂 别问 ,问就是不懂 0x01 复现环境和Exp准备 漏洞影响范围 Windows 7 Windows Server 2008 R2 W ...

  9. Kubernetes的Service运行原理

    一.为什么Servcie能定位到Pod 因为Pod的IP是不固定的,所以Kubernetes需要Service,除此之外它还可以在多个Pod间负载均衡 Service的访问入口,其实是宿主机的kube ...

  10. MySQL GROUP_CONCAT()函数 -- 字段合并查询

    在做查询的时候遇到一个问题,今天分享一下解决方法. 先看一下我想要什么效果. 清单名称类型要点,后面两列为清单步骤(外键表) 但我并不想让主表的内容重复那么多遍,于是 distinct去重.子查询.左 ...