IOS开发入门之View Programming Guide for iOS 视图编程指南 - iOS
白羽 2018-11-26 来源 :网络 阅读 859 评论 0

摘要:本文将带你了解IOS开发入门View Programming Guide for iOS 视图编程指南 - iOS,希望本文对大家学IOS有所帮助。

    本文将带你了解IOS开发入门View Programming Guide for iOS 视图编程指南 - iOS,希望本文对大家学IOS有所帮助。



        

1 有关 Windows and Views

每个应用都至少有一个 window 和一个 view。

1.1 添加额外的 Window

一般在有外界显示设备的时候才需要添加额外的 window

下面的代码举了一个例子,这里假定对象实现了方法 externalWindow,externalWindow 存储一个 window 的引用


   

- (void)configureExternalDisplayAndShowWithContent:(UIViewController*)rootVC

{

   // Configure the content only if a second screen is available.

   if ([[UIScreen screens] count] > 1) {

      UIScreen* externalScreen = [[UIScreen screens] objectAtIndex:1];

      CGRect screenBounds = externalScreen.bounds;

 

      // Configure the window

      self.externalWindow = [[UIWindow alloc] initWithFrame:screenBounds];

      self.externalWindow.windowLevel = UIWindowLevelNormal;

      self.externalWindow.screen = externalScreen;

 

      // Install the root view controller

      self.externalWindow.rootViewController = rootVC;

 

      // Show the window, but do not make it key.

      self.externalWindow.hidden = NO;

   }

   else {

        // No external display available for configuration.

   }

}

   

2 View 和 Window 层级

2.1 View 层级原理

UIKit中的每个 view,底层都拥有一个 layer 对象,通常都是CALayer。大多数情况下都直接通过 UIView 操作;当需要更多控制的时候可以通过 layer 执行操作。

注意:bar button item 不是 view,所以不能直接访问它的 layer。实际上 bar button item 是直接继承自 NSObject,而 layer 是 UIView 中定义的,所以bar button item没有。

 

 
 

 <喎?"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPrrL0MS2r7utsuO74bbUIHZpZXe21M/zu+bWxrT6wuu1xMTayN29+NDQu7q05tbY08OjrNPIxuTKx9Ta09C2r7uttcTH6b/2z8KjrNbY08OxyNbY0MK0tL2o0ru49tDCtcTE2sjd18rUtM/7usTQobrctuChozwvcD4NCjxoMyBpZD0="211-视图层级和子视图管理">2.1.1 视图层级和子视图管理

如果子视图是完全不透明的话,会遮盖父视图的内容。父视图将子视图存放在一个有序的数组中,所以后添加的(子视图数组最后的)会在最上面显示。

父视图改变大小会引起子视图的大小随之变化,可以自定义这种变化。还有父视图被隐藏、改变父视图的透明度(alpha),或者对父视图的坐标系统应用数学转换等,都会影响到子视图。

UIResponder 和它的子类可以响应事件,并处理事件,UIView就是继承自 UIResponder。

 

 
 

 

点击事件的响应是从上到下一层一层判断的,如果最后没有任何对象做出响应,通常就丢弃了。

2.1.2 视图绘图周期

第一次绘图的时候系统保存一个绘图内容的快拍(snapshot),如果之后再没有对内容改动,那么不会再调用绘图代码,都直接使用这个快拍;如果有了改动,就重新生成一个快拍,周而复始。

当视图的内容或者外观发生变化的时候可以使用 setNeedsDisplay 和 setNeedsDisplayInRect 方法进行重绘;注意如果改变了视图的几何形状,这个方法就失效了。这两个方法是等待当前 run loop 执行到最后的时候,再将刚才设置的所有重绘操作一次执行完成。

 

有关几何形状的变化,需要看下面的 Content Modes

UIView 的子类,通常重写 drawRect: 方法,在这个方法里面写绘图代码。这个方法不需要自己调用。

2.1.3 Content Modes 内容模式

当发生下列两种情况时,内容模式就会应用:

改变视图的 frame 或者 bounds 矩形的宽或高。 指定一个转换,比如视图的 transform 属性的缩放比例


   

@property(nonatomic)                 UIViewContentMode contentMode;                // default is UIViewContentModeScaleToFill

   


   

typedef NS_ENUM(NSInteger, UIViewContentMode) {

    UIViewContentModeScaleToFill,

    UIViewContentModeScaleAspectFit,      // contents scaled to fit with fixed aspect. remainder is transparent

    UIViewContentModeScaleAspectFill,     // contents scaled to fill with fixed aspect. some portion of content may be clipped.

    UIViewContentModeRedraw,              // redraw on bounds change (calls -setNeedsDisplay)

    UIViewContentModeCenter,              // contents remain same size. positioned adjusted.

    UIViewContentModeTop,

    UIViewContentModeBottom,

    UIViewContentModeLeft,

    UIViewContentModeRight,

    UIViewContentModeTopLeft,

    UIViewContentModeTopRight,

    UIViewContentModeBottomLeft,

    UIViewContentModeBottomRight,

};

   

 

 
 

 

UIViewContentModeRedraw 通常都不需要使用这个值,尤其在标准系统视图中不要使用。

2.1.4 可伸缩的视图

可以指定一个区域为可伸缩的,可以沿着一个轴或者两个轴伸缩。下图显示了视图自身显示的失真

 

 
 

 

contentStretch 属性用来指定可伸缩的区域。但是这个属性iOS6之后被废弃了,通常这个属性都是用在 view 的背景 UIImage 对象,所以现在用 [UIImage resizableImageWithCapInsets:] 达到相同效果。

2.1.5 内嵌动画的支持

执行动画需要做两件事:

告诉UIKit 你想要执行动画 改变属性的值

下面这些 UIView 对象的属性都可以用作动画:

frame 以动画形式改变视图的位置和大小 bounds 以动画形式改变视图的大小 center 以动画形式改变视图的位置 transform 旋转或者伸缩视图 alpha 改变视图的透明度 backgroundColor 改变视图的背景颜色

比如通常可以用导航栏控制器控制两个视图的转换动画,这是提供的标准动画,当觉得达不到想要效果,就可以自定义。

还可以直接使用 Core Animation layers创建动画。

2.2 视图的几何(Geometry)和坐标(Coordinate)系统

 

 
 

 

每个视图和窗口都定义了自己的局部坐标系统。

2.2.1 Frame,Bounds 和 Center 属性的关系

frame 属性包含矩形框架,指定视图的大小和在父视图坐标系中的位置 bounds 属性包含了矩形边界,指定了在视图自己局部的坐标系中视图的大小(以及内容的边界) center 属性包含了父视图坐标系中视图的中点

 

 
 

 

下面3种情况,改变会有连锁反应:

改变frame 属性,bounds、center 属性也会随着改变 改变center 属性,frame 的原点会改变 bounds 属性的大小改变,frame 属性也会改变

2.2.2 坐标系变换

利用仿射变换可以改变整个视图的大小、位置或者方向。

transform 属性可以修改变换方式,并且有动画。

2.2.3 点像素

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

一个 point 并不一定和 一个像素相等,千万不要有相等的假设。

2.2.4 视图的运行交互模式

 

 
 

 

考虑下面几种情况:

1.用户触摸屏幕

2.硬件给UIKit框架报告触摸事件

3.UIKit 框架把触摸事件包装为一个 UIEvent 对象,并且分配给适当的视图。

4.视图的 event-handling 代码响应事件。比如,你的代码可以:

改变视图或者子视图属性(frame,bounds,alpha 等等) 调用 setNeedsLayout 方法来标记需要布局更新的视图或者子视图。 调用 setNeedsDisplay 或者 setNeedsDisplayInRect: 方法来标记需要重绘的视图或它的子视图。 通知 controller 有关一些数据块的修改

上面这都是由你来决定做哪些事情。

如果使用了手势识别来处理事件,就不要重写任何手势识别的方法;同样,如果视图不包含任何子视图或者它的大小没有改变,不要重写 layoutSubviews 方法;当你的视图内容在运行时候需要改变,或者你正在使用比如Uikit或者Core Graphics的原生技术来进行绘图时,才需要重写 drawRect:

2.3 有效使用视图的要点

自定义视图需要考虑性能问题;优化绘图代码之前,先测量性能,然后定个性能标准再优化。

2.3.1 视图并不需要总是对应一个试图控制器

视图控制器提供的功能比如:协调视图在屏幕上的显示,协调视图在屏幕上的移动,释放内存,旋转视图等。

2.3.2 尽可能少的进行自定义绘图

2.3.3 内容模型的优势

应该避免使用 UIViewContentModeRedraw。总是使用 setNeedsDisplay 或者 setNeedsDisplayInRect:

2.3.4 尽可能的将视图声明为不透明的

对于透明的渲染会增加性能的损耗。

2.3.5 当滚动的时候调整视图的绘制行为

滚动的时候非常损耗性能,所以可以考虑在滚动的时候暂时降低内容的渲染质量。滚动停止的时候再恢复。

2.3.6 不同通过嵌入子视图来自定义控件

永远不要给系统控件自行添加视图,这样会导致很多错误发生。

3 Windows 窗口

这章节涉及内容不常用,用时再看 - Windows

窗口职责:

包含应用的可视化内容 在视图触摸事件和其他应用对象之间扮演递送者 通常和视图控制器协作,来适应方向的变化

3.1 涉及窗口的任务

Use the window object to convert points and rectangles to or from the window’s local coordinate system. Use window notifications to track window-related changes.

3.2 创建和配置窗口

3.2.1 用IB创建窗口

3.2.2 代码创建窗口

3.2.3 给窗口添加内容

3.2.4 改变窗口层级

3.3 监视窗口的改变

UIWindowDidBecomeVisibleNotification UIWindowDidBecomeHiddenNotification UIWindowDidBecomeKeyNotification UIWindowDidResignKeyNotification

3.4 在额外的设备上显示内容

3.4.1 处理屏幕连接和断开通知

3.4.2 为额外的设备配置一个窗口

3.4.3为额外的设备配置屏幕模式

4 Views 视图

view 的职责:

布局和子视图管理:

view 定义它对于父视图的默认 resize 行为 视图可以管理一系列子视图 视图可以根据需要调整子视图的大小和位置 视图可以将它的坐标系转化为其他视图或者窗口的坐标系

绘制和动画:

视图在它的矩形区域绘制内容 view 的某些属性可以以动画的形式变换到新值

事件处理:

视图可以收到触摸事件 视图可以参与到响应链

4.1 创建和配置视图对象

4.1.1 使用IB创建视图对象

可以查看 Resource Programming Guide

4.1.2 代码创建view对象


CGRect  viewRect = CGRectMake(0, 0, 100, 100);

UIView* myView = [[UIView alloc] initWithFrame:viewRect];

   

4.1.3 设置view 的属性

view 的一些关键属性的用法

                            

  属性

  用法

aplha, hidden, opaque    这些属性影响view 的透明度,alpha 和 hidden 属性直接改变 view 透明度;opaque 属性告诉系统是否应该混合视图的显示。设置为YES 可以提升性能。    

bounds, frame, center, transform    center 和 frame 属性都和父视图相关,而bounds属性在自己的坐标系中定义了可视化内容区域。transform 属性常用语动画或者用复杂的方式移动 view。    

autoresizingMask, autoresizesSubviews    这些属性影响视图和子视图的自动 resieze 行为。autoresizingMask 属性控制视图在父视图中如何响应变化。autoresizesSubviews 属性控制是否当前视图的子视图要完全被 resize。    

contentMode, contentStretch, contentScaleFactor    这些属性影响 view 里面内容的渲染行为。    

gestureRecognizers, userInteractionEnabled, multipleTouchEnabled, exclusiveTouch    这些属性影响 view 如何处理触摸事件。    

backgroundColor, subviews, drawRect:方法, layer, (layerClass 方法)    这些属性和方法帮你管理 view 中的实际内容。    

4.1.4 为以后的验证标记 view

tag 可以用一个整数值来标记特定的 view。默认这个属性为 0。

找到标记的view,可以使用 viewWithTag: 方法。

4.2 创建和管理 view 层级

4.2.1 添加和移除子视图

addSubview: 方法直接添加到最上面。


   

- (void)removeFromSuperview;

- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;

- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;

 

- (void)addSubview:(UIView *)view;

- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;

- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;

 

- (void)bringSubviewToFront:(UIView *)view;

- (void)sendSubviewToBack:(UIView *)view;

   

4.2.2 隐藏 view

设置 hidden 属性为 YES,或者将alpha 属性设置为 0.0。隐藏view 之后就不能收到触摸事件了。

如果要以动画形式将view 从可视化到隐藏,必须使用 alpha 属性。hidden 属性不是可动画的

4.2.3 从 view 层级中找出视图

两种方式:

存储相应视图的指针,比如 view controller 拥有视图的方式 给 view 的 tag 属性赋值,但数字要独一无二;然后用 viewWithTag: 方法拿到

4.2.4 转变,伸缩,旋转 view


   

// M_PI/4.0 is one quarter of a half circle, or 45 degrees.

CGAffineTransform xform = CGAffineTransformMakeRotation(M_PI/4.0);

self.view.transform = xform;

   

 

 
 

 

4.2.5 在视图层级中转换坐标

UIView 定义了下面几种方法在view 的局部坐标系中转换坐标

convertPoint:fromView: convertRect:fromView: convertPoint:toView: convertRect:toView:

类似,UIWindow也定义了几个转换方法:

convertPoint:fromWindow: convertRect:fromWindow: convertPoint:toWindow: convertRect:toWindow:

 

 
 

 

4.3 在运行时调整 view 的大小和位置

UIView 支持自动和手动布局

4.3.1 为布局改变做准备

当 view 中有下面几种事件发生的时候,布局需要改变:

view 的 bound 矩形大小发生变化 界面的方法发生变化,这通常会触发根视图的 bound 矩形变化 与 view layer相关的 Core Animation sublayer 的集合发生变化,并要求 layout 调用view 的 setNeedsLayout 或者 layoutIfNeeded 方法,让应用强制布局 调用view的 layer对象的 setNeedsLayout 方法,让应用强制布局

4.3.2 使用自动调整大小规则让布局自动变化

设置父视图 autoresizesSubviews 属性来决定子视图是否需要调整大小。如果这个属性为 YES,每个子视图的 autoresizingMask 属性决定如何变化。

                                

  Autoresizing mask

  描述

UIViewAutoresizingNone    默认值,view不会自动调整大小    

UIViewAutoresizingFlexibleHeight    当父视图的高变化的时候,视图的高也会变化。如果没有包含这个常量,视图的高不变    

UIViewAutoresizingFlexibleWidth    当父视图的宽变化的时候,视图的宽也会变化。如果没有包含这个常量,视图的宽不变    

UIViewAutoresizingFlexibleLeftMargin    视图左边界与父视图左边界的距离会按需要增大或减小。如果没有包含这个常量,将维持固定的距离    

UIViewAutoresizingFlexibleRightMargin    视图右边界与父视图右边界的距离会按需要增大或减小。如果没有包含这个常量,将维持固定的距离    

UIViewAutoresizingFlexibleBottomMargin    视图下边界与父视图下边界的距离会按需要增大或减小。如果没有包含这个常量,将维持固定的距离    

UIViewAutoresizingFlexibleTopMargin    视图上边界与父视图上边界的距离会按需要增大或减小。如果没有包含这个常量,将维持固定的距离    

 

 
 

 

4.3.3 手动调整视图布局

在自定义 view 中,如果自动布局行为没有达到期望要求,可以实现 layout    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程