IOS View编程指南笔记

我们所看到的程序

对于一切IOS APP来说,我们看的的内容,都是UIView所呈现的。

UIView如场景,UIWindow如舞台,UIView粉墨登场在UIWindow这个舞台上,使我们看到丰富多彩的界面UI。UIWindow本身没有任何内容,它只提供了一个场所来让这些UIView来显示,切换。

通常,一个APP仅有一个UIWindow作为显示的场所,当我们要进行多屏显示时,才会使用到多个UIWindow。

UIView的基本结构

1、UIView附着于UIWindow上,只有放在UIWindow上的View,才能被我们看到。

2、UIView本身又可作为容器显示并管理SubView,使界面更丰富。

3、每个UIView都有一个对应的Core Animation Layer类对象作支持。Layer类对象一般是CALayer类对象。该对象存储对应UIView对象的一些信息数据,并处理UIView的动画操作。

有了CALayer对象,主要会提供如下几点作用:

(1)CALayer对象存储了对应UIView对象的信息数据,这可以使UIView的渲染次数大大减少,我们可以尽可能的直接读取CALayer对象里面的存储的已经渲染过的数据,而不需要每次都要渲染UIView。

(2)正是因为CALayer对象存储了UIView的信息,才使得UIView的当前内容可以被操作,进而实现UIView的动画效果。

(3)我们可以通过直接操作CALayer对象来实现更丰富灵活的显示及动画效果。

UIWindow, UIView, Core Animation Layer对象关系如下图所示:

View的等级及SubView的管理

如前所述,UIView可以添加子View,进而形成superView,subView这样的父子逻辑关系。

subView被父View放到一个子View队列里面进行管理。

view显示的层级关系

最后加入的view会遮挡前面的view。

事件响应链(Event
responder chain)

当App获取到用户的操作事件后,会首先将该event传递给发生该事件最上层的subview,若该subview不响应该事件,则会传递至该view的superview进行响应,这样一直传递下去,直到该事件被响应或由程序丢弃不处理为止。这就是所谓的Event responder chain。

View的内容绘制周期

在IOS中,UIView类采取一种按需策略来绘制View的显示内容。所谓按需策略,就是指仅当你明确告知系统需要对View进行内容重绘时,系统才会调用你的绘制函数重新绘制VIew的内容,否则,系统在大多数情况下仅使用View的内容快照图片来代替View的内容显示。

具体实现如下:

1、当一个View第一次显示在屏幕时,系统会自动调用View的绘制函数,完成内容显示,同时,为内容保留一份快照图片。

2、若View的内容不发生改变,则在大多数情况下,系统仅使用快照图片来表示View内容。这里注意,系统不会主动询问是否View的内容发生了改变,需要你主动通知系统内容发生改变从而更新View显示内容。

3、当你对View的内容做出了改变,调用

setNeedsDisplay or setNeedsDisplayInRect:

方法通知系统内容发生改变,需要重绘View界面。

4、系统得知内容发生改变后,不会立即重绘View界面,而是当这轮run loop结束,准备重绘内容时,才会对改变内容的View进行重绘。

5、当系统对View进行重绘时,流程并不是统一的。对于自定义的View而言,我们需要重写

drawRect: 方法。

当然,也可以通过直接改变View对应的Layer对象的方式来改变View的内容。

6、当系统完成对View的重绘后,会采集一张新的内容快照来代表View的内容来用作多数时间的View显示。

注意,一般的View的几何形变(如拉伸缩小,不会引起内容重绘,而仅仅是内容快照的拉伸缩小)。

View的内容模式

如前所述,当View显示在屏幕上后,系统会用一张快照来代替表示内容。

这会照成这么一种情况,当我们更改View的frame等属性时,其内容(内容快照),并不一定会同时改变。对于内容显示的方式,取决于UIView对象的Content
Modes
.默认的系统会采取UIViewContentModeScaleToFill模式,使内容快照拉伸填充满整个View区域。Content
Mode的几个形式如下图:

注意,当设置了View的ContentMode后,每一次View的几何形变都会引起系统调用View的drawRect:方法来重绘View,因此应当避免使用该属性,同时对于系统View,我们绝不应该用属性。

View的坐标系统

IOS系统的坐标系统如下所示:

UIWindow, UIView都有自己的坐标系统。对于UIView常用的属性Frame,Bound,Center其属性是相对于不同坐标系统的。具体如下:

A view object tracks its size and location using its framebounds, and center properties:

  • The frame property
    contains the frame rectangle, which specifies the size and location of the view in its superview’s coordinate system.
  • The bounds property
    contains the bounds rectangle, which specifies the size of the view (and its content origin) in the view’s own local coordinate system.
  • The center property
    contains the known center point of the view in the superview’s coordinate system.

总结一下,就是view的frame,center属性其坐标系统均是对于其superview的坐标系统来说的。而bounds属性,则是对其自己的坐标系统来说的。

Frame, Center, Bounds的相互关系

Frame,Center都是相对view的superview坐标系统来说的,所以可以用作subview在superview中的定位与大小。对于位移运动,推荐改变Center属性来实现,因为Frame属性在一些变形中是不存在的。

Frame,Center,Bounds互相影响着对方,具体如下:

  • When you set the frame property, the size value in the bounds property
    changes to match the new size of the frame rectangle. The value in the center property similarly changes to match the new center point of the frame rectangle.
  • When you set the center property, the origin value in the frame changes
    accordingly.
  • When you set the size of the bounds property, the size value in the frame property
    changes to match the new size of the bounds rectangle.

View的Runtime交互模型

我们可以通过触摸等动作,和view进行实时的交互。

IOS系统中,用户动作与View的交互模型大致如下:

1、用户触摸屏幕,该事件硬件识别,并被发给了UIKit Framework。

2、该触摸事件被UIKit Framework包装成UIEvent类对象,并发给对应的事件响应View。

3、在事件响应View中,我们可以通过对应的函数,来捕获到当前的UIEvent事件(手势识别机制或重写touch系列响应函数)。

4、在View中我们自定义代码做出响应,如:

  • 调用setNeedsLayout 方法,让系统重新布局(即让系统在下一轮更新过程中,主动调用我们重写的layoutSubviews )
  • 调用 setNeedsDisplay or setNeedsDisplayInRect: 方法,让系统对View内容进行重绘。(即让系统在下一轮内容更新过程中,主动调用我们重写的drawRect: )函数。
  • 更改UIView的属性,或通知某个controller对象。

关于View使用的Tips

Apple官方对View的使用做出若干建议,个人感觉比较重要的摘要如下:

1、尽量设置View的Opaque属性为YES。当View的Opaque属性设置为YES时,UIKit框架就不会在去检查View后面是否有可以渲染的东西(因为你已经明确说明该View是不透明的),提高UIKit框架渲染速度。

2、不要在已有的UIControlr对象中添加subview。我们对于UIControl对象的使用,应该尽量保持原生态。虽然对UIControl添加自己的subview技术是可行的,但这么做是危险的。因为当Apple更新版本时,UIControl对象的实现细节可能会改变,而导致我们添加了subview的程序运行失败。

参考资料:

Apple官方文档

View Programming Guide for iOS

https://developer.apple.com/library/prerelease/ios/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/WindowsandViews/WindowsandViews.html#//apple_ref/doc/uid/TP40009503-CH2-SW16

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 14:51:19

IOS View编程指南笔记的相关文章

线程同步-iOS多线程编程指南(四)-08-多线程

首页 编程指南 Grand Central Dispatch 基本概念 多核心的性能 Dispatch Sources 完结 外传:dispatch_once(上) Block非官方编程指南 基础 内存管理 揭开神秘面纱(上) 揭开神秘面纱(下) iOS多线程编程指南 关于多线程编程 线程管理 Run Loop 线程同步 附录 Core Animation编程指南 Core Animation简介 基本概念 渲染架构 几何变换 查看目录 中文手册/API ASIHTTPRequest Openg

(译)IOS block编程指南 1 介绍

Introduction(介绍) Block objects are a C-level syntactic and runtime feature. They are similar to standard C functions, but in addition to executable code they may also contain variable bindings to automatic (stack) or managed (heap) memory. A block ca

iOS ---Extension编程指南

当iOS 8.0和OS X v10.10发布后,一个全新的概念出现在我们眼前,那就是应用扩展.顾名思义,应用扩展允许开发者扩展应用的自定义功能和内容,能够让用户在使用其他app时使用该项功能.你可以开发一个应用扩展来执行某些特定的任务,用户使用该扩展后就可以在多个上下文环境中执行该任务.比如说,你提供了一个能让用户把内容分享到社交网站的扩展,用户可以在阅读邮件信息或者上网时通过app扩展来发表评论.或者说,如果你提供了一个能展示当前比赛分数的扩展,那么用户可以把它放在通知中心,这样在他们打开To

iOS多线程编程指南(二)线程管理

当应用程序生成一个新的线程的时候,该线程变成应用程序进程空间内的一个实体.每个线程都拥有它自己的执行堆栈,由内核调度独立的运行时间片.一个线程可以和其他线程或其他进程通信,执行I/O操作,甚至执行任何你想要它完成的任务.因为它们处于相同的进程空间,所以一个独立应用程序里面的所有线程共享相同的虚拟内存空间,并且具有和进程相同的访问权限. 一.线程成本 多线程会占用你应用程序(和系统的)的内存使用和性能方面的资源.每个线程都需要分配一定的内核内存和应用程序内存空间的内存.管理你的线程和协调其调度所需

iOS线程编程指南

原英文网址为: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html 同步 在应用程序中的多个线程的存在开辟了潜在的问题,关于安全访问到资源从多个执行线程.两个线程修改相同的资源可能会相互干扰,以意想不到的方式.例如,一个线程可能会覆盖其他人的更改或应用程序置于未知和潜在无效的状态.如果你很幸运,已损坏的资源可能会导致

View Programming Guide for iOS 视图编程指南 - iOS

1 有关 Windows and Views 每个应用都至少有一个 window 和一个 view. 1.1 添加额外的 Window 一般在有外界显示设备的时候才需要添加额外的 window 下面的代码举了一个例子,这里假定对象实现了方法 externalWindow,externalWindow 存储一个 window 的引用 - (void)configureExternalDisplayAndShowWithContent:(UIViewController*)rootVC { // C

iOS蓝牙编程指南 -- 核心蓝牙概述

小引 随着穿戴设备和智能家居的热情不断,app蓝牙的开发也很火热,基于iOS蓝牙的开发资料有不少,但是最最值得学习的必然是apple自家的文档啦,我之前的项目基于蓝牙4.0,开发过程中用到Core Bluetooth框架,算是我学习的笔记吧!涉及到几个部分,我打算分开把他们整理出来,本篇文章通过对Core Bluetooth Programming Guide的翻译,为大家介绍iOS蓝牙4.0编程的一些术语和概念,后续文章将会简单介绍下代码的流程.本人实力有限,了解的深度不是很广,还请各位看官轻

安卓权威编程指南-笔记 (第29章定制视图与触摸事件)

1.定制视图 Android自带众多优秀的标准视图与组件,但有时为追求独特的应用视觉效果,我们仍需创建定制视图. 定制视图分为两大类别: 简单视图: 简单视图内部也可以很复杂,之所以归为简单类别,是因为简单视图不包括子视图,而且简单视图几乎总是会执行定制绘制. 聚合视图:聚合视图由其他视图对象组成,聚合视图通常管理着子视图,但不负责执行定制绘制,图形绘制任务都委托给了各个子视图. 创建定制视图的所需的三大步骤: 选择超类.对于简单定制视图而言,View是个空白画布,因此它作为超类最常见,对于聚合

安卓权威编程指南-笔记(第21章 XML drawable)

在Andorid的世界里,凡事要在屏幕上绘制的东西都可以叫drawable,比如抽象图形,Drawable的子类,位图图形等,我们之前用来封装图片的BitmapDrawable就是一种drawable. 本章我们还会看到更多的drawable:state list drawable.shape drawable和layer list drawable. 这三个drawable都定义在XML文件中,可以归为一类,统称为XML drawable. shape drawable 使用ShapeDraw