UIKit程序员iOS Developer

苹果API翻译之UIView(一)

2017-11-05  本文已影响115人  rogertan30
霉霉镇楼

每个iOS新版本的发布,苹果都会对API进行更新,作者总是会忽略这方便的学习。另外,很多知识点独立的都有涉及,但是并没有形成系统的知识体系。作者拟通过这样的方式,督促自己的学习,以及做到对知识点的总结。

说明:英文为原文,斜体字为中文翻译(机翻+个人理解),粗体是作者根据自己的经验补充的说明,数字小标是作者认为需要另开文章研究的知识点。

UIView

An object that manages the content for a rectangular area on the screen.
一个管理屏幕上矩形区域的内容的对象。

Overview

Views are the fundamental building blocks of your app's user interface, and the UIView class defines the behaviors that are common to all views. A view object renders content within its bounds rectangle and handles any interactions with that content.The UIView class is a concrete class that you can instantiate and use to display a fixed background color. You can also subclass it to draw more sophisticated content. To display labels, images, buttons, and other interface elements commonly found in apps, use the view subclasses provided by the UIKit framework rather than trying to define your own.

视图是应用程序用户界面的基本构建块,UIView类定义了所有视图通用的行为。视图对象在其边界矩形内呈现内容,并处理与该内容的任何交互。UIView类是一个具体的类,您可以实例化并使用它来显示固定的背景颜色。您也可以将其子类化以绘制更复杂的内容。要显示应用程序中常见的标签,图像,按钮和其他界面元素,请使用UIKit框架提供的视图子类,而不是尝试定义自己的。

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

因为视图对象是您的应用程序与用户交互的主要方式,所以他们有很多职责。这里仅仅呈现它的部分作用:

Views can be nested inside other views to create view hierarchies, which offer a convenient way to organize related content. Nesting a view creates a parent-child relationship between the child view being nested (known as the subview) and the parent (known as the superview). A parent view may contain any number of subviews but each subview has only one superview. By default, when a subview’s visible area extends outside of the bounds of its superview, no clipping of the subview's content occurs. Use the clipsToBounds property to change that behavior.

视图可以嵌套在其他视图中以创建视图层次结构,这提供了组织相关内容的便捷方式。嵌套视图会在嵌套的子视图(称为子视图)和父级(称为超级视图)之间创建父子关系。父视图可以包含任意数量的子视图,但每个子视图只有一个超级视图。默认情况下,当子视图的可见区域扩展到其超级视图的边界之外时,不会发生剪辑子视图的内容。使用clipsToBounds来更改该行为。 (作者说一句:clipsToBounds常用在给UIImageView添加图片时,图标的尺寸大于控件尺寸时。)

The geometry of each view is defined by its frame and bounds properties. The frame property defines the origin and dimensions of the view in the coordinate system of its superview. The bounds property defines the internal dimensions of the view as it sees them and is used almost exclusively in custom drawing code. The center property provides a convenient way to reposition a view without changing its frame or bounds properties directly.

每个视图的尺寸由其framebounds属性定义。frame属性定义视图的初始位置和它在父视图坐标系中的尺寸。bounds属性定义视图的内部尺寸。center属性提供了一种方便的方式来重新定位视图,而不直接改变其视图framebounds属性。

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

有关如何使用UIView该类的详细信息,请参阅查看iOS编程指南

Creating a View

Normally, you create views in your storyboards by dragging them from the library to your canvas. You can also create views programmatically. When creating a view, you typically specify its initial size and position relative to its future superview. For example, the following example creates a view and places its top-left corner at the point (10, 10) in the superview's coordinate system (once it is added to that superview).

通常,您可以通过将图形拖放到画布中,从而在故事板中创建视图。您也可以以编程方式创建视图。创建视图时,您通常会指定其相对于其未来超级视图的初始大小和位置。例如,以下示例创建一个视图,并将其左上角放置在超级视图坐标系中的点(10,10)(一旦添加到该超级视图中)。

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

To add a subview to another view, call the addSubview: method on the superview. You may add any number of subviews to a view, and sibling views may overlap each other without any issues in iOS. Each call to the addSubview: method places the new view on top of all other siblings. You can specify the relative z-order of 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.

要将子视图添加到另一个视图,请调用superview上的方法addSubview:。您可以将任意数量的子视图添加到视图中,并且子视图可能在iOS中相互重叠,没有任何问题。每次调用addSubview:方法将新视图放在所有其他子视图之上。您可以通过使用insertSubview:aboveSubview:和方法insertSubview:belowSubview:添加子视图来指定子视图的相对次序。您还可以使用该方法exchangeSubviewAtIndex:withSubviewAtIndex:交换已添加的子视图的位置。

After creating a view, create Auto Layout rules to govern how the size and position of the view change in response to changes in the rest of the view hierarchy. For more information, see Auto Layout Guide.

创建视图后,创建自动布局规则以管理视图的大小和位置如何更改以响应视图层次结构的其余部分中的更改。有关详细信息,请参阅自动布局指南。

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.

视图绘制根据需要进行。当首次显示视图时,或者由于布局更改而使其全部或部分变得可见时,系统会要求视图绘制其内容。对于包含使用UIKit或Core Graphics的自定义内容的视图,系统调用该视图的drawRect:方法。您执行此方法负责将视图的内容绘制到当前图形上下文中,此方法的调用时之前由系统自动设置的。这将使你可以创建视图内容,并在之后显示在屏幕。

作者说一句:在实际开发中,当我们需要在一个View上通过上下文绘制视图时,可以将绘制视图的代码写在drawRect:中,因为在drawRect:中会自动创建上下文,我们只需要实现剩下的绘制代码即可。大致代码如下:

- (void)drawRect:(CGRect)rect{  
    CGContextRef context = UIGraphicsGetCurrentContext();  
    ...
}

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.

当您的视图的实际内容发生变化时,您有责任通知系统您的视图需要重新绘制。您可以通过调用setNeedsDisplay或视图的方法setNeedsDisplayInRect:来执行此操作。这些方法让系统知道它应该在下一个绘图循环中更新视图。因为它等待直到下一个绘图周期来更新视图,您可以在多个视图上调用这些方法来同时更新它们。

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绘制的更多信息,请参阅OpenGL ES编程指南

For detailed information about the view drawing cycle and the role your views have in this cycle, see View Programming Guide for iOS.

有关视图绘制周期的详细信息以及您的视图在此周期中的角色,请参阅查看iOS编程指南

Animations

Changes to several view properties can be animated—that is, changing the property creates an animation starting at the current value and ending at the new value that you specify. The following properties of the UIView class are animatable:

对这几个视图属性的更改可以拥有动画效果,也就是说,更改属性将创建一个从当前值开始的动画,并以您指定的新值结束。UIView该类的以下属性是可动画的:

To animate your changes, create a UIViewPropertyAnimator object and use its handler block to change the values of your view's properties. The UIViewPropertyAnimator class lets you specify the duration and timing of your animations, but it performs the actual animations. You can pause a property-based animator that is currently running to interrupt the animation and drive it interactively. For more information, see UIViewPropertyAnimator.

要更改动画,请创建一个UIViewPropertyAnimator对象并使用其代码块来更改视图属性的值。该UIViewPropertyAnimator类让您指定动画的持续时间和时机,并且会执行实际的动画。您可以暂停当前运行的基于属性的动画,同时您可以中断动画并以交互方式重新启动动画。有关更多信息,请参阅UIViewPropertyAnimator

作者说一句:UIViewPropertyAnimator是iOS10新添加的属性,它与以前实现动画的不同之处在于,我们可以暂停和重启动画。简单的说其可以更细腻的制作和控制动画。扩展阅读:如何使用iOS 10的UIViewPropertyAnimator做动画

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类的方法。唯一可能不是严格必要的是创建视图对象本身,但所有其他操作都应该发生在主线程上。

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类或标准系统视图不提供所需功能的情况下才能这样做。子类需要更多的工作来实现视图并调整其性能。

For information about ways to avoid subclassing, see 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:

当进行UIView子类化时,只有少数方法应该被重写,还有许多可以根据需要重写的方法。因为UIView是一个高度可配置的类,还有许多方法来实现复杂的视图行为,而不会重写自定义方法,这在子类的替代方法部分中有所讨论。同时,以下列表包括您可能会考虑重写在您的UIView子类中的方法:

作者挖坑:为什么从nib加载视图时,是调用的这个序列化构造方法?从nib创建view的过程跟序列号,反序列化有什么关系?[1]

作者挖坑:为什么在swift中即使用代码实现UIView子类的构造方法,也需要实现required init?(coder aDecoder: NSCoder)方法?[2]

作者挖坑:简单的说,就是在手势冲突时,用来判断执行哪个手势操作的代理方法。比如ScrollView上的子控件拥有一个滑动手势,子控件实现gestureRecognizerShouldBegin代理方法,当在这个子控件上滑动时,可以在代理方法中进行判断若:return YES ,该手势会被拦截(不会传递给 ScrollView 进行滚动)。若:return NO, 该手势会传递下去(传递给 ScrollView 进行滚动)。更多关于手势的操作,咱们也挖一个坑,以后补上。[4]

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.

许多视图行为可以在不需要子类化的情况下进行配置。在开始重写方法之前,请考虑修改以下属性或行为是否会提供所需的行为

(作者说一句:简单的说,就是苹果给你提供了有关布局,绘制,动画,手势相关的API,你能用最好就直接用,别总是想着自己造轮子了。)

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类的许多属性都是可动画效果呈现的,这意味着对这些属性的更改可以触发系统生成的动画。开始动画只需要一行代码就可以表明任何后续的变化都应该是动画的。有关动画支持视图的更多信息,请参阅Animations

Topics

Creat a View Objcet

--

Configuring a View’s Visual Appearance

--

Configuring the Event-Related Behavior

作者挖坑:关于exclusiveTouch的研究报告 [5]

--

Configuring the Bounds and Frame Rectangles

--

Managing the View Hierarchy

后话

这是API翻译的第一期。我发现在学习的过程中,又会不断引出新的知识点,这些知识点并不是一两句能说得清的,就比如我在下面留的坑。我的想法是,利用每个周末输出一篇API翻译的文章,然后工作日再将文章中的坑补齐。尽量做到有文字,有DEMO的形式。先这么决定吧,喜欢文章的朋友,请关注我的公众号SwiftCoder,如果有幸转载,也请保留公众号的名称。另外有建议的朋友,也请留言。您的鼓励是我坚持的动力。(真正开始写文章,才明白这句话的分量)

如果你喜欢我的文章请关注我的公众号SwiftCoder,我会编写高质量的原创iOS开发内容。

image.png
  1. 留坑: xib文件的初始化与initWithCoder的关系

  2. 留坑: 为什么必须调用required init?(coder aDecoder: NSCoder)

  3. 留坑: Masonry详解

  4. 留坑: 手势操作

  5. 留坑:修改transform和修改frame的区别

上一篇下一篇

猜你喜欢

热点阅读