View Programming Guide for iOS(Link)

     那就先从阅读文档看起吧,看完这个,就去看UIVIew的API了,然后写一些demo,UIView还没时间看。我也不知道在哪里点开这篇文档的超链接了,哦,是从UIView的API点开的超链接。或者从UIKit的推荐文档来看,哎呀,苹果官网的视屏教程也还没看。

     我现在需要看的是线程和动画,好的吧,看完UIView再慢慢整理顺序了。

     View Programming Guide for iOS 是14年的文档 , 接下来要看的文档

                             Core Animation Programming Guide

   

Introduction: -- 介绍

 

About Windows and Views -- 关于windows和views

--In iOS, you use windows and views to present your application’s content on the screen. Windows do not have any visible content themselves but provide a basic container for your application’s views. Views define a portion of a window that you want to fill with some content. For example, you might have views that display images, text, shapes, or some combination thereof. You can also use views to organize and manage other views.

      在iOS中,你是用windows和view把你的app的内容展示在屏幕上的。windows是“不包含”任何“可见内容”的窗口,但是windows提供了最基本的容纳之所给views。Views是window的组成部分, view是你想展示的视图的容纳之所。所以你可以用views来展示图片,文字,阴影,以及这些内容的组合等等。你也可以用views来容纳view。


At a Glance -- 简概

--UIKit and other system frameworks provide predefined views that you can use to present your content. In places where the predefined views do not provide what you need, you can also define custom views and manage the drawing and event handling yourself.

     每一个app至少要有一个window和一个view 来组成。UIKit框架提供了预定义的views,你可以直接使用这些views,也可以自定义view。


Views Manage Your Application’s Visual Content -- veiws管理你app的可见内容

--A view is an instance of the UIView class (or one of its subclasses) and manages a rectangular area in your application window. Views are responsible for drawing content, handling multitouch events, and managing the layout of any subviews. Drawing involves using graphics technologies such as Core Graphics, OpenGL ES, or UIKit to draw shapes, images, and text inside a view’s rectangular area.

      一个view必须是UIView 类的实例,而且一个view 管理了app中一个window的矩形区域。view负责绘制内容,操纵多点触摸事件,同时也管理子view的布局。绘制视图的内容可以使用Core Graphics, OpenGL ES这些图形技术来绘制,也可以使用UIKit来绘制。绘制视图内容是指,在view管理的矩形区域内,绘制例如形状、图片、文字这些东西。

--A view responds to touch events in its rectangular area either by using gesture recognizers or by handling touch events directly. In the view hierarchy, parent views are responsible for positioning and sizing their child views and can do so dynamically. This ability to modify child views dynamically lets your views adjust to changing conditions, such as interface rotations and animations.

      一个view要响应触碰事件的话,要么就是直接处理触碰事件,要么就是通过手势识别器来响应。在views的层次结构中,是由父视图来掌控子视图的位置和大小的,甚至可以动态地布置,所以你可以用这个动态掌控的特性来让你的子视图变形或者实现动画效果了。

--You can think of views as building blocks that you use to construct your user interface. Rather than use one view to present all of your content, you often use several views to build a view hierarchy. Each view in the hierarchy presents a particular portion of your user interface and is generally optimized for a specific type of content. For example, UIKit has views specifically for presenting images, text and other types of content.

     你也可以把views视作建筑大楼的一个构件,虽然建筑大楼也可是构件的一种。但是你还是不要用一个view来展示你所有视图内容,一般来说,你会用好几个views来搭建你的视图层次。在视图层次中的每一个view都有它特定的意义,也就是你会优化一个view来展示某一种特定的视图内容。例如,在展示图片、文字、或者其他视图内容的时候,你会根据情形来设计优化这个view,各司其职。


--Relevant Chapters: View and Window Architecture, Views

    相关章节,也是在这个文档里的。看链接 

 

Windows Coordinate the Display of Your Views  -- window负责协调view的展示

--A window is an instance of the UIWindow class and handles the overall presentation of your application’s user interface. Windows work with views (and their owning view controllers) to manage interactions with, and changes to, the visible view hierarchy. For the most part, your application’s window never changes. After the window is created, it stays the same and only the views displayed by it change. Every application has at least one window that displays the application’s user interface on a device’s main screen. If an external display is connected to the device, applications can create a second window to present content on that screen as well.

    window是UIWindow类的实例,并且处理你app上所有的用户界面的展示。window通过使用view和view controller来管理视图层次中的视图的交互,以及视图层次中的视图的改变。但是,你的window永远不会被更改。一个window创建之后,就只有它管理的view会改变,window自身是不会变的。但是如果外设要连接手机的时候,app也是可以创建第二个windows来在外设屏幕上展示视图的。

Relevant Chapters: Windows

 


Animations Provide the User with Visible Feedback for Interface Changes -- 动画提供了可视化的用户界面变化过程

--The system defines standard animations for presenting modal views and transitioning between different groups of views. However, many attributes of a view can also be animated directly. For example, through animation you can change the transparency of a view, its position on the screen, its size, its background color, or other attributes. And if you work directly with the view’s underlying Core Animation layer object, you can perform many other animations as well.

核心动画层对象,你还可以执行一些更酷炫的动画效果。

Relevant Chapters: Animations


The Role of Interface Builder  --  界面建造器的作用

--Interface Builder is an application that you use to graphically construct and configure your application’s windows and views. Using Interface Builder, you assemble your views and place them in a nib file, which is a resource file that stores a freeze-dried version of your views and other objects. When you load a nib file at runtime, the objects inside it are reconstituted into actual objects that your code can then manipulate programmatically.

      用户界面建造器是一个软件,你可以使用界面建造器以图解的方式来配置你app的window和view。你在界面建造器搭建的window和view会以nib file的形式储存,nib file是一个专门存储 雪藏版本 的view的文件。nib file中的view实例可以在运行期加载,所以你可以以编程的方式使用nib file。nib file完全支持iOS,它可大量简化你搭建界面的工作,所以苹果公司推荐你使用。

--For more information about how to use Interface Builder, see Interface Builder User Guide.

    用户建造器使用指南,看超链接。

--For information about how view controllers manage the nib files containing their views, see Creating Custom Content View Controllers in View Controller Programming Guide for iOS.

   view controller编程指南,看超链接。

See Also -- 相关文章推荐

  • A view controller presides over all of the views in a single view hierarchy and facilitates the presentation of those views on the screen. For more information about view controllers and the role they play, see View Controller Programming Guide for iOS.

         view controller 统领视图层次中的某一个层次的所有view,并且促进这些view在屏幕上显示。所以,看超链接。

  • Views are the key recipients of gesture and touch events in your application. For more information about using gesture recognizers and handling touch events directly, see Event Handling Guide for iOS.

        view是手势和触碰事件的接收者,如何使用手势识别器和处理触碰事件,搜索Event Handling Guide for iOS.

  • Custom views must use the available drawing technologies to render their content. For information about using these technologies to draw within your views, see Drawing and Printing Guide for iOS.

        如何使用图形绘制技术渲染view的视图内容,看超链接

  • In places where the standard view animations are not sufficient, you can use Core Animation. For information about implementing animations using Core Animation, see Core Animation Programming Guide.

        如果标准的动画技术不足够你使用,那就使用核心动画吧,看超链接。

 

View and Window Architecture  -- view和window结构体系

--Views and windows present your application’s user interface and handle the interactions with that interface. UIKit and other system frameworks provide a number of views that you can use as-is with little or no modification. You can also define custom views for places where you need to present content differently than the standard views allow.

    view和window负责展示用户界面,并且处理客户与用户界面的交互。UIKit和其他系统框架提供了一系列现成的view给你使用,你可以直接用,或者稍加修改再使用。实在不行,你还可以自定义view

--Whether you use the system views or create your own custom views, you need to understand the infrastructure provided by the UIView and UIWindow classes. These classes provide sophisticated facilities for managing the layout and presentation of views. Understanding how those facilities work is important for making sure your views behave appropriately when changes occur in your application.

    无论你使用系统提供的标准view ,还是自定义的view,你都必须了解UIView and UIWindow 类,这些类提供了复杂的工具来管理视图的展示和布局。


View Architecture Fundamentals -- view体系基础

--A view object defines a rectangular region on the screen and handles the drawing and touch events in that region. A view can also act as a parent for other views and coordinate the placement and sizing of those views. The UIView class does most of the work in managing these relationships between views, but you can also customize the default behavior as needed.

      一个view是 UIView 类的实例,一个view实例在它自己的绘制矩形范围内绘制图形并且处理触碰事件。view既可以当爸爸,也可以是别人的儿子。 UIView 类在管理视图集的关系中做了大量的工作,但是你还是可以自定义默认的关系的行为

★--Views work in conjunction with Core Animation layers to handle the rendering and animating of a view’s content. Every view in UIKit is backed by a layer object (usually an instance of the CALayer class), which manages the backing store for the view and handles view-related animations. Most operations you perform should be through the UIView interface. However, in situations where you need more control over the rendering or animation behavior of your view, you can perform operations through its layer instead.

       ★ view与核心动画层一起工作,以处理视图内容的渲染和动画过程。UIKit的每一个view底层都是由CALayer类的实例来支持的 ,CALayer类的实例负责管理view的库存和处理与view相关的动画过程。大多数情况下,你直接操作view就可以了。但是如果你要更多的渲染和动画的控制权的话,你也可以操作view内部的CALayer类实例。

--Figure 1-1 shows the view architecture from the ViewTransitions sample application along with the relationship to the underlying Core Animation layers. The views in the application include a window (which is also a view), a generic UIView object that acts as a container view, an image view, a toolbar for displaying controls, and a bar button item (which is not a view itself but which manages a view internally).

--Every view has a corresponding layer object that can be accessed from that view’s layer property. (Because a bar button item is not a view, you cannot access its layer directly.) Behind those layer objects are Core Animation rendering objects and ultimately the hardware buffers used to manage the actual bits on the screen.

     Figure 1-1  图展示了window、view、layer之间的关系,window也可以是做一个特殊的view。window是一个view的容器,而且window是唯一的。每一个view内部都有一个layer实例对象,你可以通过view的layer属性来访问它。虽然UIButton不是一个view,但是它内部也维护了一个view对象,你也可以直接button的layer对象。

       ★在layer实例对象的底层是一个核心动画渲染对象,最底层就是硬件缓冲区,硬件缓冲区管理屏幕上的每一bit


Figure 1-1  Architecture of the views in a sample application

ios uicollectionview 弧形布局_Core

--The use of Core Animation layer objects has important implications for performance. The actual drawing code of a view object is called as little as possible, and when the code is called, the results are cached by Core Animation and reused as much as possible later. Reusing already-rendered content eliminates the expensive drawing cycle usually needed to update views. Reuse of this content is especially important during animations, where the existing content can be manipulated. Such reuse is much less expensive than creating new content.

     核心动画层对象的使用对性能的影响极为重要。★一个view实例 ”实际绘制视图的代码 “是尽可能少被调用的,一旦被调用,这些代码产生的视图首先是被核心动画层对象缓存起来的,然后尽可能地被复用的。复用已经渲染过的视图内容,消除了更新视图时所需的昂贵的绘制周期,虽然昂贵,该用的时候还是要用的。复用比新建廉价得多,消耗性能更少。


View Hierarchies and Subview Management -- 视图层次以及管理子视图

--In addition to providing its own content, a view can act as a container for other views. When one view contains another, a parent-child relationship is created between the two views. The child view in the relationship is known as the subview and the parent view is known as the superview. The creation of this type of relationship has implications for both the visual appearance of your application and the application’s behavior.

--Visually, the content of a subview obscures all or part of the content of its parent view. If the subview is totally opaque, then the area occupied by the subview completely obscures the corresponding area of the parent. If the subview is partially transparent, the content from the two views is blended together prior to being displayed on the screen. Each superview stores its subviews in an ordered array and the order in that array also affects the visibility of each subview. If two sibling subviews overlap each other, the one that was added last (or was moved to the end of the subview array) appears on top of the other.

       后来的子视图会盖在前面的子视图上面。子视图按照先来后到的顺序贴在父视图上。子视图可设置透明度。

--The superview-subview relationship also impacts several view behaviors. Changing the size of a parent view has a ripple effect that can cause the size and position of any subviews to change too. When you change the size of a parent view, you can control the resizing behavior of each subview by configuring the view appropriately. Other changes that affect subviews include hiding a superview, changing a superview’s alpha (transparency), or applying a mathematical transform to a superview’s coordinate system.

    更改父视图的布局及属性也会牵连到子视图的布局及属性。

--The arrangement of views in a view hierarchy also determines how your application responds to events. When a touch occurs inside a specific view, the system sends an event object with the touch information directly to that view for handling. However, if the view does not handle a particular touch event, it can pass the event object along to its superview. If the superview does not handle the event, it passes the event object to its superview, and so on up the responder chain. Specific views can also pass the event object to an intervening responder object, such as a view controller. If no object handles the event, it eventually reaches the application object, which generally discards it.

     ★你在视图层次上的顺序部署,决定了你的app怎么去响应事件。当一个触碰事件发生在某个view的内部时,系统会直接把该事件的实例传递给该view处理。但是如果该view不对该事件进行处理的话,那么该事件就会传递给该view的父视图。

         如果父视图也不处理的话,那就传递给父视图的父视图,一直上去,这种响应关系也叫做响应链。当然,特定的view也可以把事件对象传递给中介的响应对象esponder object, 例如 view controller也是一个响应对象。

       

For more information about how to create view hierarchies, see Creating and Managing a View Hierarchy.


The View Drawing Cycle -- 视图绘制周期

--The UIView class uses an on-demand drawing model for presenting content. When a view first appears on the screen, the system asks it to draw its content. The system captures a snapshot of this content and uses that snapshot as the view’s visual representation. If you never change the view’s content, the view’s drawing code may never be called again. The snapshot image is reused for most operations involving the view. If you do change the content, you notify the system that the view has changed. The view then repeats the process of drawing the view and capturing a snapshot of the new results.

      UIView 类是“按需”绘制模型来展示视图的,首次展示视图的时候,系统会先获取视图内容的快照,然后将快照当做可视内容进行显示。如果你的视图内容不改变,则实际的代码不会再被调用,而是一直复用快照,实际上大多数操作视图的操作都是在操作快照而已。当视图内容发生改变的时候你才需要重新捕获快照,来展示新的视图内容。

--When the contents of your view change, you do not redraw those changes directly. Instead, you invalidate the view using either the setNeedsDisplay or setNeedsDisplayInRect: method. These methods tell the system that the contents of the view changed and need to be redrawn at the next opportunity. The system waits until the end of the current run loop before initiating any drawing operations. This delay gives you a chance to invalidate multiple views, add or remove views from your hierarchy, hide views, resize views, and reposition views all at once. All of the changes you make are then reflected at the same time.

     系统调用UIview的setNeedsDisplay or setNeedsDisplayInRect:方法来无效化视图,当视图内容改变的时候,系统不会立刻绘制视图内容,而是等待当前线程“运行循环期”结束后才开始绘制的操作。

--Note: Changing a view’s geometry does not automatically cause the system to redraw the view’s content. The view’s contentMode property determines how changes to the view’s geometry are interpreted. Most content modes stretch or reposition the existing snapshot within the view’s boundaries and do not create a new one. For more information about how content modes affect the drawing cycle of your view, see Content Modes.

      注意点:改变视图的几何形状并不会引起系统重新绘制视图,而是UIView通过自己的contentMode属性来修改视图的几何形状。大多数的内容模式也是这样,通过修改已存在的快照的边界和位置来达到修改几何形状的要求,而不是重新绘制一个快照。更多关于内容模型的信息,看下一段落Content Modes.。

--When the time comes to render your view’s content, the actual drawing process varies depending on the view and its configuration. System views typically implement private drawing methods to render their content. Those same system views often expose interfaces that you can use to configure the view’s actual appearance. For custom UIView subclasses, you typically override the drawRect: method of your view and use that method to draw your view’s content. There are also other ways to provide a view’s content, such as setting the contents of the underlying layer directly, but overriding the drawRect: method is the most common technique.

      系统的视图一般都是通过实现私有的方法来完成视图内容的渲染,但是也提供了一些公开的接口来给你修改系统视图的外观。如果你是通过子类化UIView来自定义视图,那么你可以用 drawRect:方法来绘制你的视图内容,也可以通过直接修改view内部的layer对象来达到绘制视图的目的。建议使用drawRect:方法

--For more information about how to draw content for custom views, see Implementing Your Drawing Code.

      更多关于绘制自定义视图的内容的信息,看超链接 Implementing Your Drawing Code.。

Content Modes  -- 内容模式,涉及视图内容填充frame和bounds的图片变形。

--Each view has a content mode that controls how the view recycles its content in response to changes in the view’s geometry and whether it recycles its content at all. When a view is first displayed, it renders its content as usual and the results are captured in an underlying bitmap. After that, changes to the view’s geometry do not always cause the bitmap to be recreated. Instead, the value in the contentMode property determines whether the bitmap should be scaled to fit the new bounds or simply pinned to one corner or edge of the view.

内容模式是指,每一个view都有自己的模式来控制在“视图的几何形状发生改变时”是否回收再利用视图的内容,或者怎么去再利用视图的内容。当一个view第一次展示视图时,它是从底层的位图中获取渲染的结果的,其后该view 的几何形状发生改变时,不会再创建新的位图,而是通过UIView的contentMode属性来缩放移动视图来满足几何形状改变的要求。

--The content mode of a view is applied whenever you do the following:

    只要你执行了以下的操作,都会用到内容模式:

  • Change the width or height of the view’s frame or bounds rectangles. 

          //修改view的框架或者边界的大小

  • Assign a transform that includes a scaling factor to the view’s transform property. 

         //赋值给view的transform属性,致使view发生形变。

--By default, the contentMode property for most views is set to UIViewContentModeScaleToFill, which causes the view’s contents to be scaled to fit the new frame size. Figure 1-2 shows the results that occur for some content modes that are available. As you can see from the figure, not all content modes result in the view’s bounds being filled entirely, and those that do might distort the view’s content.

    默认情况,UIView通过设置view的contentMode属性值为 UIViewContentModeScaleToFill, 该情况下,view的内容填充frame的大小,而不是bounds的大小。下面几幅图展示了contentMode不同值的效果,所以并非所有的内容模式都填充满view的bounds,此时视图的内容可能发生扭曲,注意,view的frame和bounds是两个独立的概念。


Figure 1-2  Content mode comparisons

ios uicollectionview 弧形布局_ide_02

--Content modes are good for recycling the contents of your view, but you can also set the content mode to the UIViewContentModeRedraw value when you specifically want your custom views to redraw themselves during scaling and resizing operations. Setting your view’s content mode to this value forces the system to call your view’s drawRect: method in response to geometry changes. In general, you should avoid using this value whenever possible, and you should certainly not use it with the standard system views.

    将contentMode属性值设置为UIViewContentModeRedraw时,发生几何形遍将强制系统重新绘制视图

For more information about the available content modes, see UIView Class Reference.


Stretchable Views  -- 可拉伸的view,常用于设置Image对象

--You can designate a portion of a view as stretchable so that when the size of the view changes only the content in the stretchable portion is affected. You typically use stretchable areas for buttons or other views where part of the view defines a repeatable pattern. The stretchable area you specify can allow for stretching along one or both axes of the view. Of course, when stretching a view along two axes, the edges of the view must also define a repeatable pattern to avoid any distortion. Figure 1-3 shows how this distortion manifests itself in a view. The color from each of the view’s original pixels is replicated to fill the corresponding area in the larger view.


Figure 1-3  Stretching the background of a button

ios uicollectionview 弧形布局_ide_03

--You specify the stretchable area of a view using the contentStretch property. This property accepts a rectangle whose values are normalized to the range 0.0 to 1.0. When stretching the view, the system multiplies these normalized values by the view’s current bounds and scale factor to determine which pixel or pixels need to be stretched. The use of normalized values alleviates the need for you to update the contentStretch property every time the bounds of your view change.

       通过赋值给view的contentStretch属性来设置view的可拉伸区域,该属性值的范围是0.0 to 1.0。然后是通过“边界值”和一个”比例因子“和该“属性的值”相乘得出可拉伸的区域的,具体看该属性的api。在swift中已抛弃,而是resizableImageWithCapInset属性了。看不懂,是可拉伸区域是指某个子视图设置为可拉伸吗?

--The view’s content mode also plays a role in determining how the view’s stretchable area is used. Stretchable areas are only used when the content mode would cause the view’s content to be scaled. This means that stretchable views are supported only with the UIViewContentModeScaleToFill, UIViewContentModeScaleAspectFit, and UIViewContentModeScaleAspectFill content modes. If you specify a content mode that pins the content to an edge or corner (and thus does not actually scale the content), the view ignores the stretchable area.

      只有view的contentMode属性值设置为UIViewContentModeScaleToFill, UIViewContentModeScaleAspectFit, and UIViewContentModeScaleAspectFill 时,view的视图内容才可以被拉伸。

Note: The use of the contentStretch property is recommended over the creation of a stretchable UIImage object when specifying the background for a view. Stretchable views are handled entirely in the Core Animation layer, which typically offers better performance.

     注意:可拉伸view的处理代码完全是通过核心动画层处理的。


Built-In Animation Support -- 内置的动画支持

--One of the benefits of having a layer object behind every view is that you can animate many view-related changes easily. Animations are a useful way to communicate information to the user and should always be considered during the design of your application. Many properties of the UIView class are animatable—that is, semiautomatic support exists for animating from one value to another. To perform an animation for one of these animatable properties, all you have to do is:

内置动画的实现都是通过操作view内部的layer对象,你可以通过UIView 类一些属性实现动画效果,从一个值动画过渡到另一个值,都是内置支持的。要用这些动画属性实现动画效果,你只需要做以下操作:

    1、Tell UIKit that you want to perform an animation.

      2、Change the value of the property.

      一、告诉UIkit你想要动画效果。二、给响应的属性赋值

--Among the properties you can animate on a UIView object are the following:

  一个view对象的涉及动画的属性有

  • frame—Use this to animate position and size changes for the view.

         改变view的大小和位置

  • bounds—Use this to animate changes to the size of the view.

         只能改变view的大小

  • center—Use this to animate the position of the view.

         只能改变view的位置

  • transform—Use this to rotate or scale the view.

         旋转或者缩放view

  • alpha—Use this to change the transparency of the view.

         修改view的透明度

  • backgroundColor—Use this to change the background color of the view.

         背景颜色

  • contentStretch—Use this to change how the view’s contents stretch.

         内容拉伸的方式

--One place where animations are very important is when transitioning from one set of views to another. Typically, you use a view controller to manage the animations associated with major changes between parts of your user interface. For example, for interfaces that involve navigating from higher-level to lower-level information, you typically use a navigation controller to manage the transitions between the views displaying each successive level of data. However, you can also create transitions between two sets of views using animations instead of a view controller. You might do so in places where the standard view-controller animations do not yield the results you want.

--In addition to the animations you create using UIKit classes, you can also create animations using Core Animation layers. Dropping down to the layer level gives you much more control over the timing and properties of your animations.

     下降到layer层代码操作动画,你可以更好地设计定时器和使用动画的属性。

--For details about how to perform view-based animations, see Animations. For more information about creating animations using Core Animation, see Core Animation Programming Guide and Core Animation Cookbook.

       关于如何执行基于视图的动画,请看超链接。核心动画的编程指南,以及如何编程动画。


View Geometry and Coordinate Systems -- 视图几何以及坐标系统

--The default coordinate system in UIKit has its origin in the top-left corner and has axes that extend down and to the right from the origin point. Coordinate values are represented using floating-point numbers, which allow for precise layout and positioning of content regardless of the underlying screen resolution. Figure 1-4 shows this coordinate system relative to the screen. In addition to the screen coordinate system, windows and views define their own local coordinate systems that allow you to specify coordinates relative to the view or window origin instead of relative to the screen.

     UIKit的坐标系,默认左上角为坐标原点,向右为x轴,向下为y轴。坐标值用浮点数,不依赖于当前手机的分辨率。除了手机屏幕的坐标系之外,window和view也有自身的独立的坐标系。


Figure 1-4  Coordinate system orientation in UIKit

ios uicollectionview 弧形布局_ide_04

--Because every view and window defines its own local coordinate system, you need to be aware of which coordinate system is in effect at any given time. Every time you draw into a view or change its geometry, you do so relative to some coordinate system. In the case of drawing, you specify coordinates relative to the view’s own coordinate system. In the case of geometry changes, you specify coordinates relative to the superview’s coordinate system. The UIWindow and UIView classes both include methods to help you convert from one coordinate system to another.

      因为view和window都有自己的坐标系,所以你在绘制和布局视图的时候必须清晰自己在相对于哪个坐标系下绘图。在绘制的情况下,你使用的是view的坐标系,而在几何变形的情况下,你使用的是父视图的坐标系。window和view 都提供了从一个坐标系切换到另一个坐标系的相关方法。


Important: Some iOS technologies define default coordinate systems whose origin point and orientation differ from those used by UIKit. For example, Core Graphics and OpenGL ES use a coordinate system whose origin lies in the lower-left corner of the view or window and whose y-axis points upward relative to the screen. Your code must take such differences into account when drawing or creating content and adjust coordinate values (or the default orientation of the coordinate system) as needed.

★注意事项: Core Graphics 和 OpenGL ES 图形技术使用的坐标系和iOS默认的坐标系是不一样的,它们的原点默认是左下角,y轴在上,x轴在右。所以在iOS使用这些技术相关的代码时,注意坐标系的转换。

 


The Relationship of the Frame, Bounds, and Center Properties

                                                                                                                          -- frame,bounds和center属性的区别

A view object tracks its size and location using its frame, bounds, and center

  • The frame property contains the frame rectangle, which specifies the size and location of the view in its superview’s coordinate system.

frame属性的矩形中的大小和位置是指相对于父视图坐标系而言的。即frame的矩形是用父视图中的矩形作为坐标系来描述的。

  • 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.

bounds属性的矩形中的大小和位置是指相对于view自身坐标系(frame)而言的。bounds的用frame的矩形作为坐标系来描述

  • The center property contains the known center point of the view in the superview’s coordinate system.

    center属性是相对于父视图坐标系而言的。

--You use the center and frame properties primarily for manipulating the geometry of the current view. For example, you use these properties when building your view hierarchy or changing the position or size of a view at runtime. If you are changing only the position of the view (and not its size), the center property is the preferred way to do so. The value in the center property is always valid, even if scaling or rotation factors have been added to the view’s transform. The same is not true for the value in the frame property, which is considered invalid if the view’s transform is not equal to the identity transform.

     如果你是想在运行期间改变view的大小和位置,那就用framecenter属性。center属性的值在view 发生形变的时候仍然有效,但是frame属性值就不一定有效了,如果形变与合规的形变不一致,frame属性的值是不正确的。

--You use the bounds property primarily during drawing. The bounds rectangle is expressed in the view’s own local coordinate system. The default origin of this rectangle is (0, 0) and its size matches the size of the frame rectangle. Anything you draw inside this rectangle is part of the view’s visible content. If you change the origin of the bounds rectangle, anything you draw inside the new rectangle becomes part of the view’s visible content.

bounds属性一般用于view的绘制期间。bounds矩形在view自身的坐标系中表达,默认情况下bounds矩形的原点是相对于frame的(0, 0),大小跟随frame矩形的大小。bounds矩形是用来限制可见视图的,所以你更换bounds的原点,那么可见视图的位置也跟随着改变。如下图所示。

Figure 1-5 shows the relationship between the frame and bounds rectangles for an image view. In the figure, the upper-left corner of the image view is located at the point (40, 40) in its superview’s coordinate system and the size of the rectangle is 240 by 380 points. For the bounds rectangle, the origin point is (0, 0) and the size of the rectangle is similarly 240 by 380 points.

Figure 1-5  Relationship between a view's frame and bounds

ios uicollectionview 弧形布局_iOS_05

Although you can change the frame, bounds, and center properties independent of the others, changes to one property affect the others in the following ways:

     ★ 修改frame, boundscenter 属性时(会影响到其他属性),要注意以下对情况:

  • 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.

         修改frame属性时,boundscenter的值也会为了适应frame而做出相应的变化

  • When you set the center property, the origin value in the frame changes accordingly.

         当你设置center属性的值时,frame的中心也会跟着移动。

  • 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.

         当你设置bounds属性的尺寸值超出frame的大小时,frame的尺寸值也会跟着改变,以适应bounds的尺寸。

--By default, a view’s frame is not clipped to its superview’s frame. Thus, any subviews that lie outside of their superview’s frame are rendered in their entirety. You can change this behavior, though, by setting the superview’s clipsToBounds property to YES. Regardless of whether or not subviews are clipped visually, touch events always respect the bounds rectangle of the target view’s superview. In other words, touch events occurring in a part of a view that lies outside of its superview’s bounds rectangle are not delivered to that view.

       默认情况下,view 的视图内容只是参看父视图的坐标系而已,它不会因为超出父视图的frame坐标系而被裁剪,而是超出边界来展示。但是你可以通过设置view的clipsToBounds属性为true来裁剪视图的内容,使其限制在父视图的frame内。无论子视图的内容是否被裁剪来适应父视图的frame,触碰事件的有效触碰范围都是只遵循父视图的bounds属性。


Coordinate System Transformations  -- 坐标系统的切换

--Coordinate system transformations offer a way to alter your view (or its contents) quickly and easily. An affine transform is a mathematical matrix that specifies how points in one coordinate system map to points in a different coordinate system. You can apply affine transforms to your entire view to change the size, location, or orientation of the view relative to its superview. You can also use affine transforms in your drawing code to perform the same types of manipulations to individual pieces of rendered content. How you apply the affine transform therefore depends on context:

       仿射变换是一个数学矩阵,它指定一个坐标系中的点如何映射到另一个坐标系中的点。所以你可以使用“仿射变换”来更改子视图在父视图中的大小、位置、方向。也可以将仿射变换应用于视图内容的各个部分。仿射变换的应用取决于上下文。一般用于动画过程。

  • To modify your entire view, modify the affine transform in the transform  property of your view.

         修改view的transform属性,可以通过仿射变换修改整个视图。

  • To modify specific pieces of content in your view’s drawRect: method, modify the affine transform associated with the active graphics context.

        如果只是想在drawRect: 方法代码中修改视图内容的片段,那么你就要修改和图形上下文相关的仿射变换。

--You typically modify the transform property of a view when you want to implement animations. For example, you could use this property to create an animation of your view rotating around its center point. You would not use this property to make permanent changes to your view, such as modifying its position or size a view within its superview’s coordinate space. For that type of change, you should modify the frame rectangle of your view instead.

而不能用于修改视图在父视图中坐标系中的大小和位置。

Note: When modifying the transform property of your view, all transformations are performed relative to the center point of the view.

transform属性所产生的变换过程都是相对于view的center属性来执行的。

--In your view’s drawRect: method, you use affine transforms to position and orient the items you plan to draw. Rather than fix the position of an object at some location in your view, it is simpler to create each object relative to a fixed point, typically (0, 0), and use a transform to position the object immediately prior to drawing. That way, if the position of the object changes in your view, all you have to do is modify the transform, which is much faster and less expensive than recreating the object at its new location. You can retrieve the affine transform associated with a graphics context using the CGContextGetCTM function and you can use the related Core Graphics functions to set or modify this transform during drawing.

       思想:你不应该在视图的某一个固定点放置对象,而是相对于(0,0)点来放置对象。这样你就可以通过仿射变换来移动对象,而不需要在另一个固定的重新创建一个对象。你可以通过view的CGContextGetCTM方法获取到图形的上下文,你也可以通过Core Graphics技术的相关方法来在视图绘制期间设置或者修改仿射变换。

--The current transformation matrix (CTM) is the affine transform in use at any given time. When manipulating the geometry of your entire view, the CTM is the affine transform stored in your view’s transform property. Inside your drawRect: method, the CTM is the affine transform associated with the active graphics context.

current transformation matrix (CTM) 是指当前的仿射变换矩阵对象,你可以实时获取。它就是view的transform属性的值啊。

--The coordinate system of each subview builds upon the coordinate systems of its ancestors. So when you modify a view’s transform property, that change affects the view and all of its subviews. However, these changes affect only the final rendering of the views on the screen. Because each view draws its content and lays out its subviews relative to its own bounds, it can ignore its superview’s transform during drawing and layout.

      父视图的形变会引起子视图产生相应的形变,但是这只能在最终的渲染视图中呈现出来。因为子视图在绘制期间是参照自己的bounds坐标系的,期间会忽略点父视图的形变。

--Figure 1-6 demonstrates how two different rotation factors combine visually when rendered. Inside the view’s drawRect: method, applying a 45 degree rotation factor to a shape causes that shape to appear rotated by 45 degrees. Applying a separate 45 degree rotation factor to the view then causes the shape to appear to be rotated by 90 degrees. The shape is still rotated by only 45 degrees relative to the view that drew it, but the view rotation makes it appear to be rotated by more.

drawRect:方法中旋转45度,在父view的transform属性中再旋转45度

Figure 1-6  Rotating a view and its content

ios uicollectionview 弧形布局_iOS_06

--Important: If a view’s transform property is not the identity transform, the value of that view’s frame property is undefined and must be ignored. When applying transforms to a view, you must use the view’s bounds and center properties to get the size and position of the view. The frame rectangles of any subviews are still valid because they are relative to the view’s bounds.

 

--For information about modifying your view’s transform property at runtime, see Translating, Scaling, and Rotating Views. For information about how to use transforms to position content during drawing, see Drawing and Printing Guide for iOS.

     形变的相关内容参考超链接。


Points Versus Pixels --点与像素

--In iOS, all coordinate values and distances are specified using floating-point values in units referred to as points. The measurable size of a point varies from device to device and is largely irrelevant. The main thing to understand about points is that they provide a fixed frame of reference for drawing.

    在iOS中,所有的坐标值和距离都是以点为单位进行描述的。设备与设备间的一个“点单元”的大小是毫不相干的。“点单元”描述一个固定的框架,而你就是在这个框架里绘制图形。

--Table 1-1 lists the screen dimensions (measured in points) for different types of iOS-based devices in a portrait orientation. The width dimension is listed first, followed by the height dimension of the screen. As long as you design your interface to these screen sizes, your views will display correctly on the corresponding type of device.

   不同的iOS设备,“点单元”的个数是不一样的。 


Table 1-1  Screen dimensions for iOS-based devices


Device

Screen dimensions (in points)

iPhone and iPod touch devices with 4-inch Retina display

320 x 568

Other iPhone and iPod touch devices

320 x 480

iPad

768 x 1024

--The point-based measuring system used for each type of device defines what is known as the user coordinate space. This is the standard coordinate space you use for nearly all of your code. For example, you use points and the user coordinate space when manipulating the geometry of a view or calling Core Graphics functions to draw the contents of your view. Although coordinates in the user coordinate space sometimes map directly to the pixels on the device’s screen, you should never assume that this is the case. Instead, you should always remember the following:

      每种基于“点单元”的系统都提供了“用户坐标空间”,而你的代码主要也是参照这个“用户坐标空间”。虽然坐标用户空间最终都会映射到屏幕的像素点,但是你不能这样去设计你的代码。你应该用遵守以下这一点点来使用“用户坐标空间”

  • One point does not necessarily correspond to one pixel on the screen.

     一个“点单元”不需要对应屏幕上的一个“像素单元”

--At the device level, all coordinates you specify in your view must be converted to pixels at some point. However, the mapping of points in the user coordinate space to pixels in the device coordinate space is normally handled by the system. Both UIKit and Core Graphics use a primarily vector-based drawing model where all coordinate values are specified using points. Thus, if you draw a curve using Core Graphics, you specify the curve using the same values, regardless of the resolution of the underlying screen.

     你不需要管硬件层“点单元”与“像素单元”之间是如何映射的,UIKit会帮你映射好。UIKit和Core Graphics技术都是用“点单元”来描述“用户坐标空间”的,所以这两种技术间的“点单元”不需要转换,直接互用就好。

--When you need to work with images or other pixel-based technologies such as OpenGL ES, iOS provides help in managing those pixels. For static image files stored as resources in your application bundle, iOS defines conventions for specifying your images at different pixel densities and for loading the image that best matches the current screen resolution. Views also provide information about the current scale factor so that you can adjust any pixel-based drawing code manually to accommodate higher-resolution screens. The techniques for dealing with pixel-based content at different screen resolutions is described in Supporting High-Resolution Screens In Views in Drawing and Printing Guide for iOS.

     对于基于像素的图片技术,例如OpenGL ES ,iOS也提供了相应的与屏幕分辨率匹配的协定。对于app包里面的静态图片,iOS直接就定义了“像素密度”与“屏幕分辨率”之间如何匹配的协定,按照协定走就行。另外,view类里面也提供了关于”像素“与”屏幕分辨率“的比例因子的相关信息,至于如何处理像素与分辨率之间的关系,看超链接。


The Runtime Interaction Model for Views   --   运行期间视图的客户交互模型

--Any time a user interacts with your user interface, or any time your own code programmatically changes something, a complex sequence of events takes place inside of UIKit to handle that interaction. At specific points during that sequence, UIKit calls out to your view classes and gives them a chance to respond on behalf of your application. Understanding these callout points is important to understanding where your views fit into the system. Figure 1-7 shows the basic sequence of events that starts with the user touching the screen and ends with the graphics system updating the screen content in response. The same sequence of events would also occur for any programmatically initiated actions.

      任何时候,只要用户与你的界面发生交互,或者你编程改变了界面的某些东西,都会在UIkit内部产生一系列的事件,而这些事件就是用来处理这些交互的。在这些事件序列的某个点上,UIKit就会调用你定义的view类,然后让它们来响应这些事件。所以你要明白。UIKit会在事件序列的“哪个时间点” 来调用你定义的view类。下图 1 - 7 描述了从用户点击屏幕开始,到图形系统更新视图内容的一系列事件发生顺序,你在代码里面启动某一个动作方法,发生的事件也是按照这种顺序走的。

 

Figure 1-7  UIKit interactions with your view objects

ios uicollectionview 弧形布局_iOS_07

--The following steps break the event sequence in Figure 1-7 down even further and explain what happens at each stage and how you might want your application to react in response.

   下面进一步分解了图1-7的事件发生步骤:

1、The user touches the screen.

      //首先,用户点击屏幕

2、The hardware reports the touch event to the UIKit framework.

      //第二步、硬件响应触碰事件,并传递该事件到UIKit 框架

3、The UIKit framework packages the touch into a UIEvent object and dispatches it to the appropriate view. (For a detailed explanation of how UIKit delivers events to your views, see Event Handling Guide for iOS.)

      //第三步、UIKit将触碰事件打包成一个UIEvent对象,然后分发给适当的一些view对象。(关于UIKit会分发哪些事件给哪些view,网上搜索 Event Handling Guide for iOS.)

4、The event-handling code of your view responds to the event. For example, your code might:

     你写来响应事件的代码可能会是下面这样子:

Of course, it is up to you to decide which of these things the view should do and which methods it should call.

     调用或者实现view的哪些属性和方法来处理事件取决于你

  • Change the properties (frame, bounds, alpha, and so on) of the view or its subviews.

         事件来了,修改view的frame大小,透明度等等这些属性

  • Call the setNeedsLayout method to mark the view (or its subviews) as needing a layout update.

         调用setNeedsLayout方法来标记view的哪一个子视图需要更新

  • Call the setNeedsDisplay or setNeedsDisplayInRect: method to mark the view (or its subviews) as needing to be redrawn.

         调用 setNeedsDisplay or setNeedsDisplayInRect: 方法来标记view或者view的子视图为需要重新绘制

  • Notify a controller about changes to some piece of data.

         通知controller有部分数据发生了改变

5、If the geometry of a view changed for any reason, UIKit updates its subviews according to the following rules:

       //第五步、如果一个view的几何形状发生改变,UIKit会根据下面的两条规则来更新view的子视图

      如果你的view有配置了自动绘制尺寸的规则,那么UIKit就会根据这些规则来更新view的子视图。更多关于 自动绘制尺寸 的规则,看超链接。  

  • --If the view implements the layoutSubviews method, UIKit calls it.You can override this method in your custom views and use it to adjust the position and size of any subviews. For example, a view that provides a large scrollable area would need to use several subviews as “tiles” rather than create one large view, which is not likely to fit in memory anyway. In its implementation of this method, the view would hide any subviews that are now offscreen or reposition them and use them to draw newly exposed content.

       再者、如果view实现了layoutSubviews方法,那么UIKit就会调用这个方法。 所以你可以在你自定义的view中复写这个方法,view几何形状发生改变时,UIKit就会自动调用这个方法,然后就执行你的代码啦。

6、If any part of any view was marked as needing to be redrawn, UIKit asks the view to redraw itself.

       //第六步、如果之前有标记到任何视图为需要重新绘制的,那么UIKIt就会在这一步要求view进行重新绘制,自身或者子视图都要。

--For custom views that explicitly define a drawRect: method, UIKit calls that method. Your implementation of this method should redraw the specified area of the view as quickly as possible and nothing else. Do not make additional layout changes at this point and do not make other changes to your application’s data model. The purpose of this method is to update the visual content of your view.

   如果你自定义的视图显示的定义了drawRect:方法,UIKit自动调用该方法进行重新绘制。所以你在定义drawRect:方法时,就不要做过多的操作了,单纯绘图就好了。

--Standard system views typically do not implement a drawRect: method but instead manage their drawing at this time.

   系统的标准视图通常不会实现drawRect:方法,而drawRect:方法就是为了在这个时候被调用来重新绘制视图的。   

7、Any updated views are composited with the rest of the application’s visible content and sent to the graphics hardware for display.

     //第七步、至此,所有更新的视图以及相关的可见视图在这时都会被UIKIt发送到图形硬件层进行显示。

8、The graphics hardware transfers the rendered content to the screen.

    //第八步、图形硬件层结束到这些视图内容后,就把它们渲染到屏幕上


Note: The preceding update model applies primarily to applications that use standard system views and drawing techniques. Applications that use OpenGL ES for drawing typically configure a single full-screen view and draw directly to the associated OpenGL ES graphics context. In such a case, the view may still handle touch events but, because it is full-screen, it would not need to lay out subviews. For more information about using OpenGL ES, see OpenGL ES Programming Guide.

注意点:上述步骤中关于“更新视图,绘制视图的操作流程”只试用于系统标准视图以及使用绘制技术的绘制的视图。对于使用OpenGL ES技术绘制的图形,更新视图的流程并非如此。但是view管理事件的步骤仍然如上所述,只是更新视图的操作不一样而已。OpenGL ES是直接在一个全屏内绘制视图的,所以可能就不需要布局子视图这种操作,更多OpenGL ES技术,参考超链接。

 

--In the preceding set of steps, the primary integration points for your own custom views are:

    在前面的一系列步骤中,你定义的视图和事件的主要整合点在:

● The event-handling methods:

     复写的关于事件处理的方法有

  • touchesBegan:withEvent:
  • touchesMoved:withEvent:
  • touchesEnded:withEvent:
  • touchesCancelled:withEvent:

● The layoutSubviews method

      复写关于子视图布局的layoutSubviews方法

● The drawRect: method

     复写重新绘制图形的drawRect:方法,这个方法作用于运行期改变视图内容

--These are the most commonly overridden methods for views but you may not need to override all of them. If you use gesture recognizers to handle events, you do not need to override any of the event-handling methods. Similarly, if your view does not contain subviews or its size does not change, there is no reason to override the layoutSubviews method. Finally, the drawRect: method is needed only when the contents of your view can change at runtime and you are using native technologies such as UIKit or Core Graphics to do your drawing.

      上述的方法都是很常用的,也是提供给你复写的,你可以根据需求来进行复写,不一定要复写全部。

--It is also important to remember that these are the primary integration points but not the only ones. Several methods of the UIView class are designed to be override points for subclasses. You should look at the method descriptions in UIView Class Reference to see which methods might be appropriate for you to override in your custom implementations.

     上述的UIView提供给你复写的方法并不是全部,更多关于整合事件和视图的方法详情看UIView这个类。


Tips for Using Views Effectively -- 关于高效使用视图的小提示

--Custom views are useful for situations where you need to draw something the standard system views do not provide, but it is your responsibility to ensure that the performance of your views is good enough. UIKit does everything it can to optimize view-related behaviors and help you achieve good performance in your custom views. However, you can help UIKit in this aspect by considering the following tips.

       最好在系统提供的标准视图不能满足的你需求时,你才自定义视图。因为UIKit提供的视图都维护了很好的性能。

Important: Before optimizing your drawing code, you should always gather data about your view’s current performance. Measuring the current performance lets you confirm whether there actually is a problem and, if there is, gives you a baseline measurement against which you can compare future optimizations.

       tips:在优化你的代码之前,你应该首先收集你当前view运行时的性能的数据,以后可以此性能的数据作为一个基准来优化你自定义view的代码了。


Views Do Not Always Have a Corresponding View Controller -- view并非总是有一个vc对应

--There is rarely a one-to-one relationship between individual views and view controllers in your application. The job of a view controller is to manage a view hierarchy, which often consists of more than one view used to implement some self-contained feature. For iPhone applications, each view hierarchy typically fills the entire screen, although for iPad applications a view hierarchy may fill only part of the screen.

    因为一个vc一般都是对应多个view的,是管理一个视图集层次的,兄弟视图,子视图之类的。

--As you design your application’s user interface, it is important to consider the role that view controllers will play. View controllers provide a lot of important behaviors, such as coordinating the presentation of views on the screen, coordinating the removal of those views from the screen, releasing memory in response to low-memory warnings, and rotating views in response to interface orientation changes. Circumventing these behaviors could cause your application to behave incorrectly or in unexpected ways.

     vc的作用包括,调整view在屏幕上的显示,协调view从屏幕中移除,低内存警告时释放内存,旋转view视图等等。

--For more information view controllers and their role in applications, see View Controller Programming Guide for iOS.

     更多关于vc的内容,看超链接。

Minimize Custom Drawing -- 最小化你自定义的绘制过程

--Although custom drawing is necessary at times, it is also something you should avoid whenever possible. The only time you should truly do any custom drawing is when the existing system view classes do not provide the appearance or capabilities that you need. Any time your content can be assembled with a combination of existing views, your best bet is to combine those view objects into a custom view hierarchy.

     除非系统提供的view不满足你的需求,不然尽量不要自定义视图。也不要太刻意地不自定义视图,该用还是要用的。


Take Advantage of Content Modes -- 利用好内容模式Content Modes

--Content modes minimize the amount of time spent redrawing your views. By default, views use the UIViewContentModeScaleToFill content mode, which scales the view’s existing contents to fit the view’s frame rectangle. You can change this mode as needed to adjust your content differently, but you should avoid using the UIViewContentModeRedraw content mode if you can. Regardless of which content mode is in effect, you can always force your view to redraw its contents by calling setNeedsDisplay or setNeedsDisplayInRect:.

       利用好contentMode可以节省系统大量的绘图时间,默认情况view的contentMode属性值为UIViewContentModeScaleToFill,该值会缩放视图内容来填充frame矩形。尽量避免使用contentMode属性的UIViewContentModeScaleToFill值,这个会重新绘制视图,消耗大量的系统时间。在调用setNeedsDisplay or setNeedsDisplayInRect:方法绘制图时,你先不要考虑contentMode的有效性,系统会帮你优化,专心写你的代码就行。

Declare Views as Opaque Whenever Possible -- 可以的话就声明view为不透明的

--UIKit uses the opaque property of each view to determine whether the view can optimize compositing operations. Setting the value of this property to YES for a custom view tells UIKit that it does not need to render any content behind your view. Less rendering can lead to increased performance for your drawing code and is generally encouraged. Of course, if you set the opaque property to YES, your view must fill its bounds rectangle completely with fully opaque content.


Adjust Your View’s Drawing Behavior When Scrolling -- 滚动视图时调节你的view的绘制行为

--Scrolling can incur numerous view updates in a short amount of time. If your view’s drawing code is not tuned appropriately, scrolling performance for your view could be sluggish. Rather than trying to ensure that your view’s content is pristine at all times, consider changing your view’s behavior when a scrolling operation begins. For example, you can reduce the quality of your rendered content temporarily or change the content mode while a scroll is in progress. When scrolling stops, you can then return your view to its previous state and update the contents as needed.

       滚动视图很可能引起短时间内大量视图的更新。滚动视图时,你应该去修改你的视图行为,而不是去努力保证视图永远保存初始模样。例如暂时修改contentMode属性的值。


Do Not Customize Controls by Embedding Subviews -- 不要在控件中嵌入子视图

--Although it is technically possible to add subviews to the standard system controls—objects that inherit from UIControl—you should never customize them in this way. Controls that support customizations do so through explicit and well-documented interfaces in the control class itself. For example, the UIButton class contains methods for setting the title and background images for the button. Using the defined customization points means that your code will always work correctly. Circumventing these methods, by embedding a custom image view or label inside the button, might cause

     ★ 虽然技术上支持这样的操作,当时不要在子类化了UIControl的view中嵌入子视图。因为支持你定制的控件 都是“控件类”显示地提供规范的接口给你使用的来定制你的控件的。就是你只能通过系统提供的控件的一些属性和方法来美化你的控件,而不能直接就在系统提供的标准控件中嵌入子视图。