Views and Controls

Views and Controls

在屏幕上展示您的内容,并定义与该内容相关的交互。

Overview

视图和控件是应用程序用户界面的可视构件。 使用它们在屏幕上绘制和组织应用程序的内容。

75c071dc-3a79-466b-99d1-f8ef216a94aa.png

视图可以托管其他视图。 将一个视图嵌入另一个视图会在主视图(称为超视图)和嵌入视图(称为子视图)之间创建包含关系。 查看层次结构可以更轻松地管理视图。

您还可以使用视图来执行以下任一操作:

响应触摸和其他事件(直接或与手势识别器配合使用)。

使用Core Graphics或UIKit类绘制自定义内容。

支持拖放交互。

回应重点更改。

动画化视图的大小,位置和外观属性。

UIView是所有视图的根类,并定义它们的常见行为。 UIControl定义了特定于按钮,开关和用于用户交互的其他视图的其他行为。

UIView

管理屏幕上矩形区域内容的对象。

UIView-Overview

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

由于视图对象是应用程序与用户交互的主要方式,因此它们有许多责任。 这里仅仅是少数:

绘画和动画

视图使用UIKit或Core Graphics在其矩形区域中绘制内容。

一些视图属性可以动画为新值。

布局和子视图管理

视图可能包含零个或多个子视图。

视图可以调整子视图的大小和位置。

使用自动布局来定义调整视图大小和重新定位视图的规则,以响应视图层次结构中的更改。

事件处理

视图是UIResponder的一个子类,可以响应触摸和其他类型的事件。

视图可以安装手势识别器来处理常见的手势。

视图可嵌套在其他视图中以创建视图层次结构,这提供了组织相关内容的便捷方式。 嵌套视图在嵌套的子视图(称为子视图)和父视图(称为超视图)之间创建父子关系。 父视图可能包含任意数量的子视图,但每个子视图只有一个超视图。 默认情况下,当子视图的可见区域超出其超视图范围时,不会发生子视图内容的剪切。 使用clipsToBounds属性更改该行为。

每个视图的几何体由其框架和边界属性定义。 frame属性定义了其超视图坐标系中视图的原点和尺寸。 bounds属性定义了视图的内部维度,它几乎只用于自定义绘图代码。 center属性提供了一种便捷的方式来重新定位视图,而不必直接更改其框架或边界属性。
有关如何使用UIView类的详细信息,https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009503

Creating a View

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

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

要将子视图添加到其他视图,请在超级视图上调用addSubview:方法。 您可以将任意数量的子视图添加到视图中,并且兄弟视图可以在iOS中没有任何问题的情况下彼此重叠。 每次调用addSubview:方法都会将新视图置于所有其他同胞之上。 您可以通过使用insertSubview添加它来指定子视图的相对z顺序:上面的子视图和insertSubview:belowSubview:方法。 您还可以使用exchangeSubviewAtIndex:withSubviewAtIndex:方法交换已添加子视图的位置。

创建视图后,创建自动布局规则来控制视图的大小和位置如何响应视图层次结构其余部分的更改而发生更改。 有关更多信息,请参阅自动布局指南。https://developer.apple.com/library/content/documentation/UserExperience/Conceptual/AutolayoutPG/index.html#//apple_ref/doc/uid/TP40010853

视图绘制周期

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

您的视图需要重绘。 您可以通过调用视图的setNeedsDisplay或setNeedsDisplayInRect方法来实现此目的。 这些方法让系统知道它应该在下一个绘图周期中更新视图。 因为它等到下一个绘图周期才更新视图,所以可以在多个视图中调用这些方法以同时更新它们。
有关视图绘制周期和视图在此周期中的作用的详细信息,请参阅查看iOS编程指南。https://developer.apple.com/library/content/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40009503

动画

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

frame

框架矩形,它在其超视图的坐标系中描述视图的位置和大小。

Declaration
@property(nonatomic) CGRect frame;
Discussion

该矩形在其超级视图的坐标系中定义视图的大小和位置。 在布局操作中使用此矩形来设置视图的大小和位置。 设置此属性将更改由中心属性指定的点,并相应地更改边界矩形中的大小。 框架矩形的坐标始终以点表示。

更改框架矩形会自动重新显示视图,而不调用其drawRect:方法。 如果您希望UIKit在框架矩形更改时调用drawRect:方法,请将contentMode属性设置为UIViewContentModeRedraw。

此属性的更改可以是动画。 但是,如果transform属性包含非标识转换,则frame属性的值未定义,不应修改。 在这种情况下,请使用center属性重新定位视图,然后使用bounds属性调整大小。

bounds

边界矩形,用于在其自己的坐标系中描述视图的位置和大小。

Declaration
@property(nonatomic) CGRect bounds;
Discussion

默认边界原点是(0,0),其大小与frame属性中矩形的大小相同。 更改此矩形的大小部分会相对于其中心点生长或缩小视图。 更改大小还会更改框架属性中矩形的大小以匹配。 边界矩形的坐标始终以点表示。
更改边界矩形会自动重新显示视图而不调用其drawRect:方法。 如果您希望UIKit调用drawRect:方法,请将contentMode属性设置为UIViewContentModeRedraw。
此属性的更改可以是动画。

center

视图的框架矩形的中心点。

Declaration
@property(nonatomic) CGPoint center;
Discussion

中心点由其超视图坐标系中的点指定。 设置此属性会适当更新框架属性中矩形的原点。

当您想要更改视图的位置时,请使用此属性而不是frame属性。 即使缩放或旋转因子应用于视图的变换,中心点也始终有效。 此属性的更改可以是动画。

transform

指定应用于视图的变换,相对于其边界的中心。

Declaration
@property(nonatomic) CGAffineTransform transform;
Discussion

使用此属性可在其超级视图的坐标系中缩放或旋转视图的框架矩形。 (要更改视图的位置,请修改center属性。)此属性的默认值为CGAffineTransformIdentity。

相对于视图的锚点进行转换。 默认情况下,定位点等于框架矩形的中心点。 要更改锚点,请修改视图底层CALayer对象的anchorPoint属性。

此属性的更改可以是动画。

在iOS 8.0和更高版本中,transform属性不会影响自动布局。 自动布局根据未转换的帧计算视图的对齐矩形。

要动画您的更改,请创建UIViewPropertyAnimator对象并使用其处理程序块更改视图属性的值。 UIViewPropertyAnimator类允许您指定动画的持续时间和时间,但它会执行实际的动画。 您可以暂停当前正在运行的基于属性的动画设置,以中断动画并以交互方式进行驱动。 有关更多信息,请参阅UIViewPropertyAnimator。

线程考虑事项

对应用程序用户界面的操作必须在主线程上进行。 因此,您应该始终从应用程序主线程中运行的代码中调用UIView类的方法。 唯一不是严格需要的时候是创建视图对象本身,但所有其他操作应该在主线程上进行。

SubClassing Notes

UIView类是可视化内容的关键子类,它也需要用户交互。 尽管子类UIView有很多很好的理由,但建议您仅在基本UIView类或标准系统视图不提供所需的功能时才这样做。 子类化需要更多的工作来实现视图并调整其性能。
有关避免子类化的方法的信息,请参阅子类化的替代方法。https://developer.apple.com/documentation/uikit/uiview#1652896?language=objc

重写Methods

当继承UIView子类时,只有少数方法需要重写,并且许多方法可能会根据需要进行重写。 因为UIView是一个高度可配置的类,所以还有很多方法可以实现复杂的视图行为,而不会覆盖自定义方法,这在“子类化的替代方法”一节中进行了讨论。 同时,下面的列表包含了您可能会考虑在您的UIView子类中重写的方法:

初始化:

initWithFrame: - 建议您实现此方法。 除了此方法之外,您也可以实现自定义初始化方法。

initWithCoder: - 如果从storyboard或nib文件加载视图并且视图需要自定义初始化,则实现此方法。

layerClass仅当您希望视图为其后备存储使用不同的Core Animation图层时才使用此属性。 例如,如果您的视图使用平铺显示大型可滚动区域,则可能需要将该属性设置为CATiledLayer类。

Drawing and printing:

drawRect: - 如果视图绘制自定义内容,则实现此方法。 如果您的视图不执行任何自定义绘图,请避免覆盖此方法。

drawRect:forViewPrintFormatter: - 仅当您希望在打印过程中以不同方式绘制视图的内容时才实现此方法。

Layout and Constraints:

requiresConstraintBasedLayout如果视图类需要约束才能正常工作,请使用此属性。

updateConstraints - 如果您的视图需要在子视图之间创建自定义约束,请实现此方法。

alignmentRectForFrame:,frameForAlignmentRect: - 实现这些方法来覆盖视图如何与其他视图对齐。

didAddSubview :, willRemoveSubview: - 根据需要实施这些方法来跟踪子视图的添加和删除。

willMoveToSuperview:,didMoveToSuperview - 根据需要实现这些方法,以跟踪视图层次结构中当前视图的移动。

Event Handling:

gestureRecognizerShouldBegin: - 如果视图直接处理触摸事件并且可能希望防止附加的手势识别器触发其他操作,则实现此方法。

touchesBegan:withEvent :, touchesMoved:withEvent:,touchesEnded:withEvent :, touchesCancelled:withEvent: - 如果需要直接处理触摸事件,请实现这些方法。 (对于基于手势的输入,请使用手势识别器。)

子类的替代方法

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

  • addConstraint: - 为视图及其子视图定义自动布局行为。
  • autoresizingMask - 在超级视图的框架更改时提供自动布局行为。这些行为可以与约束相结合。
  • contentMode - 为视图的内容提供布局行为,而不是视图的框架。此属性还会影响内容如何缩放以适合视图以及是否缓存或重绘。

    隐藏或alpha - 更改整个视图的透明度,而不是隐藏或将alpha应用于视图的呈现内容。
  • backgroundColor - 设置视图的颜色,而不是自己绘制该颜色。
  • 子视图 - 而不是使用drawRect:方法绘制您的内容,将图像和标签子视图嵌入您想呈现的内容中。
  • 手势识别器 - 您可以使用手势识别器将Target-Action发送到目标对象,而不是子类自己截取和处理触摸事件。
  • 动画 - 使用内置的动画支持,而不是尝试自己动画变化。Core Animation提供的动画支持快速且易于使用。
  • 基于图像的背景 - 对于显示相对静态内容的视图,考虑使用具有手势识别器的UIImageView对象,而不是自己创建子类并绘制图像。或者,您也可以使用通用UIView对象,并将图像指定为视图的CALayer对象的内容。

动画是另一种对视图进行可见更改的方法,无需您继承和实现复杂的绘图代码。 UIView类的许多属性都是动画的,这意味着对这些属性的更改可以触发系统生成的动画。 开始动画只需要一行代码就可以表明任何后续的变化都应该是动画效果。 有关动画支持视图的更多信息,请参阅动画。

topics

Creating a View Object

  • initWithFrame:
    初始化并返回具有指定框架矩形的新分配的视图对象。
    -initWithCoder:

配置视图的视觉外观

  • backgroundColor:

    视图的背景颜色。
  • hideen:

    一个确定视图是否隐藏的布尔值。
  • α:

    视图的alpha值。
  • 不透明 apaque:

    一个布尔值,用于确定视图是否不透明。
  • tintColor:

    视图层次结构中的第一个非默认色调值,从视图本身开始并从视点本身开始。
  • tintAdjustmentMode:

    视图层次结构中的第一个非默认色调调整模式值,从视图本身开始并从视点本身开始。
  • clipsToBounds:

    一个布尔值,用于确定子视图是否局限于视图的边界。
  • clearsContextBeforeDrawing:

    一个布尔值,用于确定在绘制之前是否应该自动清除视图边界。
  • maskView:

    一个可选视图,其alpha通道用于屏蔽视图的内容。
  • layerClass:

    返回用于为此类的实例创建图层的类。
  • layer:

    视图的Core Animation图层用于渲染。

参考官方文档:https://developer.apple.com/documentation/uikit/uiview?language=objc

推荐阅读更多精彩内容