阅读 242

iOS·UIView Apple官方文档译文

📌 导语

我们追求技术的提升,关注技术的发展历程;作为从事技术工作的伐码猿,有个想法(仅是个人想法),这个想法工程量之大(遇到,用到,最新技术点,点点积累,及时补充吧),从事技术多年也算是对所花费时间的一个总结(算是对分享这块的一个目标吧)。

重点 -> 重点 -> 重点重要的事情说 2+1 遍),
我的「想法和行动」都在文章末尾

为此,自己本着好好学习,了解权威的目的,决定从官方 API 入手学习。
本文为「简书-白开水ln」作者原创;我的写作,希望能简化到初学者尽快入门和老司机繁琐回顾 ^_^.

在「时间 & 知识 」有限内,总结的文章难免有「未全、不足 」的地方,还望各位好友指出,以提高文章质量。

 API Reference

 首先附上官方原文地址 API Reference - UIView Class

Relationships
Inherits From 继承自: UIResponder : NSObject
Conforms To 遵守: UICoordinateSpace,UIDynamicItem,UIFocusItem,UITraitEnvironment,CALayerDelegate,NSCoding,UIAppearance,UIAppearanceContainer
Framework SDKs iOS 2.0+

Class

📌 UIView


The UIView class defines a rectangular area on the screen and the interfaces for managing the content in that area.

UIView 类在屏幕和界面上定义了一块矩形区域,用来管理那块区域的内容。

📌 Overview


At runtime, a view object handles the rendering of any content in its area and also handles any interactions with that content. The UIView class itself provides basic behavior for filling its rectangular area with a background color. More sophisticated content can be presented by subclassing UIView and implementing the necessary drawing and event-handling code yourself. The UIKit framework also includes a set of standard subclasses that range from simple buttons to complex tables and can be used as-is. For example, a UILabel object draws a text string and a UIImageView object draws an image.

在运行时,一个View对象处理它所在区域的内容渲染和交互。UIView类会使用背景颜色填充所在的矩形区域。更复杂的内容可以用UIView的子类来呈现,你自己来实现必要的绘画和事件处理代码。UIKit框架同时提供了一些标准子类,从简单的按钮到复杂的表格,你可以直接使用。如,UILabel 对象画文本字符串,UIImageView 对象画图像。

🏷
Because view objects are the main way your application interacts with the user, they have a number of responsibilities. Here are just a few:

  • Drawing and animation
    • Views draw content in their rectangular area using technologies such as UIKit, Core Graphics, and OpenGL ES.
    • Some view Declared property can be animated to new values.
  • Layout and subview management
    • A view may contain zero or more subviews.
    • Each view defines its own default resizing behavior in relation to its parent view.
    • A view can define the size and position of its subviews as needed.
  • Event handling
    • A view is a responder and can handle touch events and other events defined by the UIResponder class.
    • Views can use the addGestureRecognizer: method to install gesture recognizers to handle common gestures.

因为View对象是应用与用户交互的主要途径,他们有一系列的职责。以下列出一些:

  • 绘画和动画:
    • View在他们的矩形区域使用UIKitCore GraphicsOpenGL ES之类的技术绘画。
    • 一些视图属性可以动画到新的值。
  • 布局和子 View 管理
    • 一个View可以包含0个或多个子View
    • 每个View都定义了相对父View大小改变的默认行为。
    • 如有需要,一个View可以定义子View的大小和位置。
  • 事件处理
    • View是一个响应者,可以处理 UIResponder 类定义的触摸和其他事件。
    • View可以使用 addGestureRecognizer 方法安装手势识别器来处理常用手势。

🏷
Views can embed other views and create sophisticated visual hierarchies. This creates a parent-child relationship between the view being embedded (known as the subview) and the parent view doing the embedding (known as the superview). Normally, a subview’s visible area is not clipped to the bounds of its superview, but in iOS you can use the clipsToBounds property to alter that behavior. A parent view may contain any number of subviews but each subview has only one superview, which is responsible for positioning its subviews appropriately.

View可以内嵌到其他View,创建复杂的可视层级。这会在嵌入的View(子View)和被嵌入的View(父View)间创建父子关系。正常情况下,子View的可视区域不会被父View的边界剪辑,但在iOS里你可以使用 clipsToBounds 属性来修改这个行为。一个父View可能有多个子View,但一个子View只有一个父View,它负责确定子View的位置。

🏷
The geometry of a view is defined by its frame , bounds , and center properties. The frame defines the origin and dimensions of the view in the coordinate system of its superview and is commonly used during layout to adjust the size or position of the view. The center property can be used to adjust the position of the view without changing its size. The bounds defines the internal dimensions of the view as it sees them and is used almost exclusively in custom drawing code. The size portion of the frame and bounds rectangles are coupled together so that changing the size of either rectangle updates the size of both.

For detailed information about how to use the UIView class, see View Programming Guide for iOS .

View的几何结构是通过它的框架(frame),边界(bounds)和中心(center)属性来定义的。frame定义了View相对父View坐标系的原点和大小,一般在View布局和调整尺寸或位置时使用。center属性可以在不改变view的大小来调整view的位置。bounds定义了view的内部尺寸,几乎只在自定义绘画代码时使用。framesize部分和bounds矩形部分耦合在一起,所以可以使用两者中的一个或两个同时来改变view的大小。

更多关于如何使用 UIView 类,参见iOS View编程向导(View Programming Guide for iOS)

Note
In iOS 2.x, the maximum size of a UIView object is 1024 x 1024 points. In iOS 3.0 and later, views are no longer restricted to this maximum size but are still limited by the amount of memory they consume. It is in your best interests to keep view sizes as small as possible. Regardless of which version of iOS is running, you should consider tiling any content that is significantly larger than the dimensions of the screen.


注意
在iOS 2.x时,UIView的最大尺寸是1024*1024点,在iOS 3.0以后,不再强制限制大小,而是受限于内存消耗。让View尽可能小,无论运行在哪个版本的iOS上,都应该考虑避免View明显大于屏幕尺寸

📌 Creating a View「创建一个View」


To create a view programmatically, you can use code like the following:
以编程方式创建一个视图,您可以使用代码如下:

Objective-c

CGRect  viewRect = CGRectMake(10, 10, 100, 100);
UIView* myView = [[UIView alloc] initWithFrame:viewRect];复制代码

swift

let viewRect = CGRect(x: 10, y: 10, width: 100, height: 100)
let myView = UIView(frame: viewRect)复制代码

This code creates the view and positions it at the point (10, 10) in its superview’s coordinate system (once it is added to that superview). To add a subview to another view, you use the addSubview: method. In iOS, sibling views may overlap each other without any issues, allowing complex view placement. The addSubview: method places the specified view on top of other siblings. You can specify the relative z-order of a subview by adding it using the insertSubview:aboveSubview: and insertSubview:belowSubview: methods. You can also exchange the position of already added subviews using the exchangeSubviewAtIndex:withSubviewAtIndex: method.

这段代码创建了view,并把它放在父view坐标系的(10,10)点(一旦它被加到父view)。添加一个子view到另一个view上,用addSubview:方法。在 iOS 里,同级的view可以相互覆盖,而不会有任何问题,允许复杂的view布置。addSubview放置指定的view到它的同级view的顶部。你可以使用insertSubview:aboveSubview:insertSubview:belowSubview: 方法指定子view的相对z坐标。你也可以使用exchangeSubviewAtIndex:withSubviewAtIndex:方法交换已经添加的子view的位置。

🏷
When creating a view, it is important to assign an appropriate value to the autoresizingMask property to ensure the view resizes correctly. View resizing primarily occurs when the orientation of your application’s interface changes but it may happen at other times as well. For example, calling the setNeedsLayout method forces your view to update its layout.

当创建一个视图,适当的属性值分配给autoresizingMask,以确保视图尺寸正确。视图调整主要发生在应用程序的接口的方向变化,但也可能发生在其他时间。例如,调用setNeedsLayout方法迫使你的视图更新它的布局。

📌 The View Drawing Cycle「绘制周期」


View drawing occurs on an as-needed basis. When a view is first shown, or when all or part of it becomes visible due to layout changes, the system asks the view to draw its contents. For views that contain custom content using UIKit or Core Graphics, the system calls the view’s drawRect: method. Your implementation of this method is responsible for drawing the view’s content into the current graphics context, which is set up by the system automatically prior to calling this method. This creates a static visual representation of your view’s content that can then be displayed on the screen.

View绘画发生在需要时。当一个view第一次展示时,或者在布局变化时,它的整体或部分变得可见时,系统请求view绘出它的内容。对那些使用UIKitCore Graphics包含自定义内容的view来说,系统会调用它的 drawRect: 方法。你对该方法的实现,负责将view的内容画进当前的图形上下文(graphics context),系统自动优先调用该方法。这里创建了view内容的静态可视展现,接着会被展示在屏幕上。

🏷
When the actual content of your view changes, it is your responsibility to notify the system that your view needs to be redrawn. You do this by calling your view’s setNeedsDisplay or setNeedsDisplayInRect: method of the view. These methods let the system know that it should update the view during the next drawing cycle. Because it waits until the next drawing cycle to update the view, you can call these methods on multiple views to update them at the same time.

view的真实内容发生改变时,你有责任通知系统你的view需要重绘。通过调用viewsetNeedsDisplaysetNeedsDisplayInRect: 方法来通知。这些方法让系统知道它应该在下次绘画周期更新View.因为它一直等待直到下次绘画周期来更新View,你可以在多个view上调用这些方法,同时更新它们.

Note
If you are using OpenGL ES to do your drawing, you should use the GLKView class instead of subclassing UIView. For more information about how to draw using OpenGL ES, see OpenGL ES Programming Guide .


注意
如果你用OpenGL ES来绘画,应该用GLKView类来代替UIView.更多信息关于如何用OpenGL ES绘画,参见 iOS OpenGL ES编程向导(see OpenGL ES Programming Guide

For detailed information about the view drawing cycle and the role your views have in this cycle, see View Programming Guide for iOS.
更多关于View绘画周期和你的view的角色,参见iOS View编程向导(View Programming Guide for iOS.)

📌 Animations「动画」


Changes to several view properties can be animated—that is, changing the property creates an animation that conveys the change to the user over a short period of time. The UIView class does most of the work of performing the actual animations but you must still indicate which property changes you want to be animated. There are two different ways to initiate animations:

  • In iOS 4 and later, use the block-based animation methods. (Recommended)
  • Use the begin/commit animation methods.

改变多个View属性可以被动画展现,在一个短周期时间内,改变属性可以创建动画。UIView类做了很多执行动画的工作,但你仍然必须判断你需要哪些属性改变被动画。下面是两种不同的初始化动画方法:

  • 在iOS4.0及以后的版本中,使用基于块的动画方法(推荐)
  • 使用开始/提交(begin/commit)动画方法。

🏷
The block-based animation methods (such as animateWithDuration:animations: ) greatly simplify the creation of animations. With one method call, you specify the animations to be performed and the options for the animation. However, block-based animations are available only in iOS 4 and later. If your application runs on earlier versions of iOS, you must use the beginAnimations:context: and commitAnimations class methods to mark the beginning and ending of your animations.

基于块的动画方法(像 animateWithDuration:animations: )极大地简化了动画创建。只要调用一个方法,指定动画的参数,并且执行动画。然后,基于块的动画仅在iOS4及以后版本中可用。如果你的设备运行老版本的iOS,必须使用 beginAnimations:context:commitAnimations 类方法标记动画开始和结束。

The following properties of the UIView class are animatable:

可以做成动画UIView类的属性如下:

For more information about how to configure animations, see View Programming Guide for iOS .
更多关于如何配置动画,请参见视图iOS编程指南 View Programming Guide for iOS

📌 Threading Considerations「线程注意事项」


Manipulations to your application’s user interface must occur on the main thread. Thus, you should always call the methods of the UIView class from code running in the main thread of your application. The only time this may not be strictly necessary is when creating the view object itself but all other manipulations should occur on the main thread.

操作用户界面必须发生在主线程。因此,你必须在应用主线程调用UIView类的方法。只有在创建view对象自身时可以不用严格遵守,但其他操作必须在主线程中。

📌 Subclassing Notes「子类化(继承)说明」


The UIView class is a key subclassing point for visual content that also requires user interactions. Although there are many good reasons to subclass UIView, it is recommended that you do so only when the basic UIView class or the standard system views do not provide the capabilities that you need. Subclassing requires more work on your part to implement the view and to tune its performance.

对同样需要用户交互的可见内容来说,UIView类是一个关键的子类化点。尽管有很多好理由继承UIView,但我们只推荐在基本的UIView和系统自带的其他组件不能满足需要时继承UIView.继承UIView会在你实现的代码里消耗更多性能.(Apple写的代码比你的更好,有现成的就用现成的)。

For information about ways to avoid subclassing, see Alternatives to Subclassing .
更多关于子类化信息,请参见选择子类化 Alternatives to Subclassing

📌 Methods to Override「覆盖方法」


When subclassing UIView, there are only a handful of methods you should override and many methods that you might override depending on your needs. Because UIView is a highly configurable class, there are also many ways to implement sophisticated view behaviors without overriding custom methods, which are discussed in the Alternatives to Subclassing section. In the meantime, the following list includes the methods you might consider overriding in your UIView subclasses:

  • Initialization:
    • initWithFrame: - It is recommended that you implement this method. You can also implement custom initialization methods in addition to, or instead of, this method.
    • initWithCoder: - Implement this method if you load your view from an Interface Builder nib file and your view requires custom initialization.
    • layerClass Use this property only if you want your view to use a different Core Animation layer for its backing store. For example, if your view uses tiling to display a large scrollable area, you might want to set the property to the CATiledLayer class.
  • Drawing and printing:
    • drawRect: - Implement this method if your view draws custom content. If your view does not do any custom drawing, avoid overriding this method.
    • drawRect:forViewPrintFormatter: - Implement this method only if you want to draw your view’s content differently during printing.
  • Constraints:
  • Layout:
    • sizeThatFits: - Implement this method if you want your view to have a different default size than it normally would during resizing operations. For example, you might use this method to prevent your view from shrinking to the point where subviews cannot be displayed correctly.
    • layoutSubviews - Implement this method if you need more precise control over the layout of your subviews than either the constraint or autoresizing behaviors provide.
    • didAddSubview: , willRemoveSubview: - Implement these methods as needed to track the additions and removals of subviews.
    • willMoveToSuperview:, didMoveToSuperview - Implement these methods as needed to track the movement of the current view in your view hierarchy.
    • willMoveToWindow: , didMoveToWindow - Implement these methods as needed to track the movement of your view to a different window.
  • Event Handling:

当子类化 UIView 时,只有少数的方法你必须覆盖,大多数方法你可以按需覆盖。因为UIView是一个高度可配的类,不用覆盖父类方法,同样有很多实现复杂的行为的途径,这些在 选择子类化 一节中介绍。你可以在你的UIView子类中考虑覆盖下面列表中的方法:

  • 初始化
    • initWithFrame : 推荐覆盖。你同样可以实现自定义的初始化方法添加或代替此方法
    • initWithCoder : 如果你从一个Interface Buildernib文件加载view,并且需要自定义初始化,覆盖该方法。
    • layerClass : 仅当你的view需要用不同的Core Animation层后备保存时才要覆盖。例如,当你的view需要用平铺方式显示一块很大的可滚动区域时,你可能想要覆盖该方法返回CATiledLayer类.(这里不是很明白)
  • 绘画和打印
    • drawRect : 如果你的View画自定义的内容,就要实现该方法,否则避免覆盖该方法。
    • drawRect : forViewPrintFormatter:仅当你需要在打印时,打印不同内容(与显示不同)才需要实现该方法。
  • 约束
    • requiresConstraintBasedLayout : – 如果你的View类需要约束才能正常工作,实现该方法
    • updateConstraints : 如果你的view需要在子view间创建约束,需要实现该方法
    • alignmentRectForFrame :, frameForAlignmentRect:– 实现这些方法覆盖你的view如何与其他view对齐
  • 布局
    • sizeThatFits :: – 当你想在执行resize操作时有一个不同于默认的size,实现该方法。比如,你可以用这个方法阻止view收缩到子view不能正确显示的点
    • layoutSubviews : – 如果你需要更精确控制子view,而不是使用限制或autoresizing行为,就需要实现该方法。
    • didAddSubview :: , willRemoveSubview:跟踪子view添加或删除事件
    • willMoveToSuperview :, didMoveToSuperview 跟踪当前viewview层次里的运动
    • willMoveToWindow :,didMoveToWindow 跟踪view(即将或已经)移动到另一个Window
  • 事件处理:
    • touchesBegan:withEvent :, touchesMoved:withEvent:, touchesEnded:withEvent:,touchesCancelled:withEvent: 直接处理触摸事件(如果是手势,使用gesture recognizers)
    • gestureRecognizerShouldBegin : 如果需要直接处理触摸事件,那么需要覆盖该方法,阻止手势识别器触发额外动作。

📌 Alternatives to Subclassing「替代子类化」

Many view behaviors can be configured without the need for subclassing. Before you start overriding methods, consider whether modifying the following properties or behaviors would provide the behavior you need.

  • addConstraint: - Define automatic layout behavior for the view and its subviews.
  • autoresizingMask: - Provides automatic layout behavior when the superview’s frame changes. These behaviors can be combined with constraints.
  • contentMode: - Provides layout behavior for the view’s content, as opposed to the frame of the view. This property also affects how the content is scaled to fit the view and whether it is cached or redrawn.
  • hidden or alpha: - Change the transparency of the view as a whole rather than hiding or applying alpha to your view’s rendered content.
  • backgroundColor: - Set the view’s color rather than drawing that color yourself.
  • Subviews - Rather than draw your content using a drawRect: method, embed image and label subviews with the content you want to present.
  • Gesture recognizers - Rather than subclass to intercept and handle touch events yourself, you can use gesture recognizers to send an Target-Action to a target object.
  • Animations - Use the built-in animation support rather than trying to animate changes yourself. The animation support provided by Core Animation is fast and easy to use.
  • Image-based backgrounds - For views that display relatively static content, consider using a UIImageView object with gesture recognizers instead of subclassing and drawing the image yourself. Alternatively, you can also use a generic UIView object and assign your image as the content of the view’s CALayer object.

很多view行为可以配置而不用子类化。在你开始覆盖这些方法时,考虑是否可以修改下面的属性或行为来提供你需要的功能。

  • addConstraint: – 为view和它的子view定义自动布局行为.
  • autoresizingMask: – 当父viewframe改变时,提供自动布局行为。这些行为可以和约束(Constraint)合并
  • contentMode: -为view内容提供布局行为,与viewframe相反。这个属性同样影响内容应用view的缩放,是缓存还是重绘。
  • contentStretch:-定义view的部分可伸缩。这个行为通常用于实现按钮和其他复杂布局、可变尺寸、重绘代价高的view
  • hidden 或 alpha: 改变view的不透明度或隐藏view
  • backgroundColor: – 设置view的背景颜色
  • Subviews:不在drawRect方法里绘制你的内容,使用嵌入图片或文本子view等方式
  • Gesture recognizers: – 使用手势识别器替代自己手工处理touch事件
  • Animations:– 使用内建动画支持代替自己写动画。Core Animation提供的动画支持很快很好用
  • 基于图片的背景 – 对那些显示相对静态内容的view来说,考虑使用UIImageView对象加上手势识别替代子类化和自己绘制图片。同样,你也可以使用一般的UIView对象,分配你的图片作为viewCALayer对象内容。

🏷
Animations are another way to make visible changes to a view without requiring you to subclass and implement complex drawing code. Many properties of the UIView class are animatable, which means changes to those properties can trigger system-generated animations. Starting animations requires as little as one line of code to indicate that any changes that follow should be animated. For more information about animation support for views, see Animations.

动画是不需要子类化和实现复杂代码而让视觉改变的另一种方式。很多UIView的属性是可以动画的,意味着改变这些属性可以触发系统生成动画。启动动画只需要很少的一行代码指示那些改变需要被动画。更多view动画的信息,参考 Animations

For more information about appearance and behavior configuration, see About Views in UIKit User Interface Catalog .
更多关于外观和行为配置的信息,见 UIKit User Interface Catalog 目录里的 About Views


📌 Initializing a View Object「初始化View对象」


- initWithFrame: 使用指定的frame矩形,初始化并且返回新的View对象。

  • 声明:
    SWIFT:
    init(frame aRect: CGRect)复制代码
    OBJECTIVE-C:
- (instancetype)initWithFrame:(CGRect)frame复制代码
  • 参数
    aRect view的frame矩形,使用point测量。frame的原点是相对你将添加到的父view的。这个方法用frame矩形来设置中心点和边界。

  • 返回值:
    一个初始化的对象,如果不能创建,返回nil.

  • 说明:
    一个新的view对象必须插入到一个windowsview层级里才能使用。如果你用程序创建了一个view对象,这个方法是UIView类的指定初始器。子类可以覆盖这个方法来执行一些自定义的初始化,但必须在第一行调用super实现。
    如果你用Interface Builder来设计你的界面,这个方法在从nib文件创建view对象时不会被调用。
    nib里的对象使用initWithCoder:方法重建和初始化,它会修改view属性来匹配存储在nib文件里的属性。关于view如何从nib文件载入的详细信息,参见 Resource Programming Guide.

📌 配置View的可见外观


🏷 - backgroundColor: View的背景颜色

  • 声明
    SWIFT:
    @NSCopying var backgroundColor: UIColor?复制代码
    OBJECTIVE-C
    @property(nonatomic, copy) UIColor *backgroundColor复制代码
  • 说明:
    改变这个属性可以动画,默认值是nil,表现为透明。
  • 扩展
    • alpha
    • opaque

🏷 hidden:一个判断view是否隐藏的bool值

  • 声明
    SWIFT:
    var hidden: Bool复制代码
    OBJECTIVE-C
    @property(nonatomic, getter=isHidden) BOOL hidden复制代码
  • 说明:
    设置这个值为YES隐藏view,NO显示View,默认是NO
    一个隐藏的view从窗口消失并且不接收输入事件。然而,它还留在它的父view的子view列表中,并且跟往常一样参与autoresizing。隐藏一个带有子viewview,跟隐藏这些子view(包括他们的子view)有一样的效果。这个效果是含蓄的并且不会修改子viewhidden属性.
    如果隐藏的view是窗口的当前第一响应者,会导致下一个view成为第一响应者(得到焦点,是这个意思么?)

🏷 alpha: View的不透明度

  • 声明
    SWIFT:
    var alpha: CGFloat复制代码
    OBJECTIVE-C
    @property(nonatomic) CGFloat alpha复制代码
  • 说明:
    这个属性的值是一个浮点值,范围从0.0到1.0,0.0代表完全透明,1.0代表完全不透明。这个值只能当前view有效,不影响内嵌的子view 改变这个属性可以动画
  • 扩展
    • backgroundColor
    • opaque

参考原著
To be continued ☕️ To be continued ☕️ To be continued
☕️ 未完待续 ☕️ 未完待续 ☕️ 未完待续 ️

温馨提示:📌
更多有关本文系统文件的属性和方法及常用功能代码案例,请移步这里
→ iOS· Category注解工具类,阅读总会有点收获 ! 👀

→ iOS· Apple官方译文,阅读总会有点收获 !👀

声明:📌
有关 「官方译文 | 框架源码注解」,文章将「迁移 & 后续」,在GitHub 对应上面的两个工程下,这两个想法是个长期而持续的目标吧,如果你感觉看我写的文章对你 利大于弊 . . .;由于个人 「时间 & 知识」 有限,是心有余而力有限,欢迎你的 Star & Fork

期待


  • 如果在阅读过程中遇到 error,希望你能 Issues 我,谢谢。

  • 如果你想为【本文相关】分享点什么,也希望你能 Issues 我,我非常想为这篇文章增加更多实用的内容,谢谢。

  • 「博客原文」,对本文我会【不定时、持续更新、一些 学习心得与文章、实用才是硬道理】^_^.

About me


【我也是对所花费时间的一个总结】

我只是个【有思想的伐码猿🐒】加上【自己的学习总结☕️】写出来的文章。

↑ 《伐码吧》 ↑ ,谢谢

关注下面的标签,发现更多相似文章
评论