03.subview_and_superview

Subview and Superview

作者:PMST
文章:Views - Subview and Superview
系列:The Swift Beginner
写于:2015.04.27

正文

在很久以前,苹果公司的视图绘制机制和现在是大相径庭。那时任何一个视图拥有自己的“私人领地”——精确来说就是一个矩形。假如某个非该视图的subview想要呈现其中,这是不被允许的!因为当视图重绘(redraw)矩形区域时,会擦除所有不属于自己的内容;相应地,属于该视图的subview内容只允许在指定的矩形区域内绘制,想要“越狱”(将内容绘制到矩形框外)出去,没门!

而从OS X 10.5开始,这些条条框框都已经被废除了。目前苹果公司给出的视图绘制机制,完全摒弃了先前的那些限制。而值得庆幸的是iOS绘图就是基于新的架构!在iOS中,任何一个subview都允许从superview“越狱出去”,这意味着,打破了矩形区域的限制,子视图绘画面积不仅仅只是那么一小片区域,而是整个!此外其他视图(不属于superviewviews)能够覆盖别的视图,这在以前是不被允许的。

下面给出一个小demo,下图显示了三个相互重叠的视图。为了更直观地观看,给三个视图的背景上了色。现在问题来了,你无从得知三个视图之间的关系,比如:三个视图是相互独立?谁是谁的子视图?谁和谁是同级的?

figure1-1

事实上,三者的关系是这样的:

  • 粉色视图和红色视图是同级关系
  • 绿色视图是粉色视图的子视图

storyboard中,拖拉两个viewmain view中,分别设置背景颜色为粉色和红色;然后再次拖拽一个view到粉色视图中,设其背景颜色为绿色;现在打开nib editor查看视图层级设置。

figure1-2

小技巧:当你的应用程序在运行时想要查看视图层级关系,选择 Debug->View Debugging-> Capture View Hierarchy

关于视图在视图层级中的摆放位置是非常有讲究了,这也决定了视图的绘制顺序!

  • 相同层级的视图(属于同一个superView)绘制顺序是固定的:自上而下,只有当前者绘制完毕,才进行下一个视图绘制。特殊情况:假如后者绘制区域和前者有重叠,那么就会造成覆盖现象,前者视图呈现在后者视图之后。

  • 先绘制superview,在绘制属于父视图的subview

结合本文第一幅图进行绘制顺序讲解,粉色视图和红色视图为同一级,同属于父视图main view;粉色视图在前,红色视图为后,因此首先绘制粉色视图;粉色视图包含绿色子视图,当粉色视图绘制完毕,接下来是绘制绿色视图(注意:同级视图之间,前者所有视图,包括子视图全部绘制完毕,才进行下一个视图);最后是绘制红色视图,显然它会覆盖粉色以及绿色视图。

storyboard中设置层级关系

选中main.storyboard,左侧会罗列出所有视图场景,各视图层级关系一览无余。现在选中一个粉色视图,Editor-> Arrange -> Send Forward(其他还有 Send to Front,Send to Back,Send Backward),操作结果会把粉色视图下移到红色视图之下,意味着粉色视图在最前面,红色视图放置到最底下被遮盖。

补充一点视图层级的知识。

  • 当子视图从父视图中移除,子视图下的所有视图也将被移除;当子视图在父视图中移动位置,其下所有视图也跟着移动。

  • 子视图会继承父视图的透明程度(degree of transparency),这个很有意思。

  • 子视图绘画区域可以超出父视图限定的矩形区域,但是!父视图有权利选择显示还是隐藏那些超出范围的内容!!即clipping,我们可以通过设置视图的clipsToBounds属性来决定显示还是隐藏。

  • 父视图可以拥有多个子视图,从内存管理意义上来说,更像是一组数组;采用引用方式关联每一个子视图;视图数组负责一些添加或移除的工作,当有新的子视图加入进来,相应地数组新增一个元素,相反有子视图从父视图移除,数组要删除对应的元素。

  • 父视图的尺寸大小改变时,在它其中的子视图将会自动调整大小。

继续说说视图(UIView),前文谈及它一个特性,只有一个父视图(superview)和多个子视图(an array of UIView,注:数组是有序的!),允许你从中追踪视图层级关系;从方法上来说,isDescendantOfView:方法能够确定一个视图是否是另外一个视图的子视图;当然你也可以选择使用引用方式来获得某个视图,比如通过oulet;最后,每一个视图都能够设置一个独一无二的标签——tag属性,通过数值大小来决定层级关系,这都取决你!

代码设置层级关系

使用代码手工设置视图层级关系非常简单。最为熟悉的便是addSubview:,为一个视图添加子视图;与之对应的removeFromSuperview:,则是从父视图中移除子视图,记住一旦移除意味着释放(released),假如你打算好之后还要重用它,那么就别移除掉,继续保持住!

iOS还提供了各种事件(Events)来通知视图动态变化。当然想要使用还是有条件限制的:一.视图必须有子视图;二.使用override来重写方法,具体有:

  • didAddSubview:, willRemoveSubview:

  • didMoveToSuperview, willMoveToSuperview:

  • didMoveToWindow, willMoveToWindow:

一旦addSubview:被调用,视图(将要添加为子视图的view)会被放置到superview的子视图中的最新一个,从层级关系上来说,自上而下,它是最下面一个!因此在绘制时,它作为压轴最后绘图,所有其他视图都是在它之下。

前面说到一个视图的子视图可以看做一个数组(array of UIView),它的索引号自然就是从0开始。当然iOS也提供了一系列方法允许你从一个指定的索引号插入视图,至于放在前面还是后面也是可以选择的!另外还提供了方法能够交换两个同级关系的视图。

  • insertSubview:atIndex:

  • insertSubview:belowSubview:,insterSubview:aboveSubview

  • exchangeSubviewAtIndex:withSubviewAtIndex:

  • bringSubviewToFront:,sendSubviewToBack:

不过iOS貌似没有提供移除所有子视图的方法,这个倒是有点让人诧异的,因此我们只能自己遍历视图数组,逐个删除。

for v in myView.subviews as UIView{
    v.removeFromSuperview()
}

恩…貌似这么写好low。那么换种方式:

    (myView.subviews as [UIView]).map{$0.removeFromSuperview()}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值