UILayoutGuide


快速说明-我将来所有的帖子都将发布在我的专用网站上,并且此出版物不再更新。 谢谢阅读!


令人惊讶的是,我们不久之前就生活在一个“自动布局”世界中。 自动调整遮罩大小和CGRectMake()统治了相当长一段时间的用户界面开发领域。

但是随着苹果设备开始堆积各种点大小,很明显,开发人员要么陷入痛苦,要么因过多的框架计算而陷入困境,要么接受描述关系的力量。 后者显然胜出。

因此,自此以来,Auto Layout就一直被使用,DSL和批评。 但是,随着它的兴起,另一种布局范例也应运而生。 “间隔”视图。 或虚拟视图。 容器视图。

无论您怎么说,我们都使用过它们。 但是苹果公​​司说,有一种更好的方法。 本周,让我们聊天UILayoutGuide

但是,虚拟景色岩石(…并且我同意)

虚拟视图非常好地解决了一些布局问题。 这就是为什么我们都使用它们。 表达视图间的关系,创建用户界面的模块块或定义约束以表达视图之间的空白空间的坐标或大小,所有这些都称为虚拟视图。

实际上,即使只是希望将一组控件放在特定坐标空间的中心,也常常使用虚拟视图来包含它们。

这样,许多重要的工作都被委托给了一个从来没有真正去做任何事情的结构。 如果您反对这种想法,请问自己一个视图在iOS应用程序中的实际作用。

或者更好的是,让文档讲故事:

视图对象在其边界矩形内呈现内容,并处理与该内容的任何交互。

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

因此,几乎无可辩驳的是,视图的重要组成部分是视图,即渲染事物和处理事件。 虚拟视图,尽管它们是视图,但最好不要参与其中的任何活动,最坏情况下不要参与其中的一些活动。

使用虚拟视图,我们已经

  • 产生仅有助于定义布局的视图的成本。
  • 添加了视图层次结构的第一类成员,加入了可能与之相关的任何任务相关的所有开销。
  • 并且作为响应者链的一部分,它可以拦截一些原本不想处理的消息。

😬。

在那里,但不是真的

但是,布局指南既不是这些东西,也不会遭受任何这些问题的困扰。 这是一个非渲染视图,非常类似于其更强大的表亲UIStackView

与真实视图不同,布局指南实际上并未定义视图。 取而代之的是,它仅代表其拥有的视图的坐标系中的矩形区域。 而已。 这就是它与自动版式进行交互的原因。

该API紧密地(有意地)镜像视图的镜像:

 让scrollView = UIScrollView()//代替这个... 
让containerView = UIView()
scrollView.addSubview(containerView)containerView.widthAnchor.constraint(equalTo:scrollView.widthAnchor).isActive = true
containerView.heightAnchor.constraint(equalTo:scrollView.heightAnchor).isActive = true
containerView.leftAnchor.constraint(equalTo:scrollView.leftAnchor).isActive = true
containerView.rightAnchor.constraint(equalTo:scrollView.rightAnchor).isActive = true //我们可以这样做...
让containerLayoutGuide = UILayoutGuide()
scrollView.addLayoutGuide(containerLayoutGuide)containerLayoutGuide.widthAnchor.constraint(equalTo:scrollView.widthAnchor).isActive = true
containerLayoutGuide.heightAnchor.constraint(equalTo:scrollView.heightAnchor).isActive = true
containerLayoutGuide.leftAnchor.constraint(equalTo:scrollView.leftAnchor).isActive = true
containerLayoutGuide.rightAnchor.constraint(equalTo:scrollView.rightAnchor).isActive = true

API资料

UILayoutGuide类旨在执行以前由虚拟视图执行的所有任务,但以更安全,更有效的方式执行。

布局指南未定义新视图。 他们不参与视图层次结构。 相反,他们只是在自己的视图的坐标系中定义了一个矩形区域,该区域可以与“自动布局”交互。

上面显示的流程很简单:

  • 实例化布局指南。
  • 调用addLayoutGuide(_:)到所需的视图。
  • 在布局指南上设置有效约束。

假设您需要约束某些视图并将它们居中,但仅在视图的左下角即可。 如图所示,如果将视图切成四个角,我们想在左下角添加内容。 布局指南使此操作变得容易,就像没有行李的虚拟视图一样:

 让bottomLeftGuide = UILayoutGuide() 
view.addLayoutGuide(bottomLeftGuide)//外部约束
bottomLeftGuide.leftAnchor.constraint(equalTo:view.leftAnchor).isActive = true
bottomLeftGuide.bottomAnchor.constraint(equalTo:view.bottomAnchor).isActive = true
bottomLeftGuide.widthAnchor.constraint(等于:view.widthAnchor,乘数:0.5).isActive = true
bottomLeftGuide.heightAnchor.constraint(equalTo:view.heightAnchor,乘数:0.5).isActive = true //内部约束,为简便起见,使用伪代码
someLabel.top.equalToLayoutGuideTop
someLabel.left / right / etc //您可以在此处固定所需的所有其他视图

布局指南很好地解决了一个特定的问题,以至于苹果公司一直将它们放在iOS的最后几个发行版上,但是您可能并未真正注意到。 顶部布局指南,安全区域布局指南-您可能已经熟悉这些内容。

如果我不是很想写关于编码方面的文字,那么我可以让这个博客以一个句子开头和结尾:布局指南可以像虚拟视图一样使用,但不会阻塞视图层次结构或回应事件。

但是,😛的乐趣在哪里?

如果您想了解有关布局指南的其他一些小知识,请继续阅读。

对于De🐛-Ing

瞧,无论发生什么情况,Auto Layout都会一次又一次地狱。 您可以与向控制台吐出的文字墙打斗,也可以从中躲藏起来。 如果选择前者,请注意布局指南的identifier属性。

  bottomLeftLayoutGuide.identifier =“ BottomLeftGuide” 

当事情发生时,您至少知道布局指南是否是问题的一部分(这是成功的一半):

  //当约束突破时,它将显示在类似于以下内容的日志中 
“ ”

请注意,“ NS”和“ UI”的前缀是系统保留的,UIKit使用它们作为其创建的布局指南。

您可以使用的另一种技术是在运行时查询布局指南的layoutFrame 。 有时,必须在同一视图层次结构中同时使用基于框架的方法和“自动布局”,这可以极大地帮助您。

  CGRect guideRect = someLayoutGuide.layoutFrame 
aNonAutoLayoutView.frame = CGRectMake(0,guideRect.size.height,100,100)

但是请记住,因为布局框架是从“自动布局”派生的,所以您需要确保在安装此属性之前必须先安装约束。 到版面指南的所有权视图被称为layoutSubviews ,这将获得预期的结果。

此外,如果需要继续沿布局调试路径进行操作,则可能需要以下两个组件:

  • constraintsAffectingLayout:for:)函数
  • 还有hasAmbigiousLayout属性

使用上面的功能,您可以查看给定轴(即垂直或水平)的所有约束。 使用它来查看是否有任何影响其的意外约束:

 让constraintsEffectingVertical:[NSLayoutConstraint] = bottomLeftGuide.constraintsAffectingLayout(用于:.horizo​​ntal) 

最后,布尔属性完全按照其命名方式运行。 它的实用性在于,您可以使用符号断点轻松地在布局指南中检查不确定的约束。 如果您像我一样,有时候您希望在这种情况发生时节目完全停止。 有时,我会将其包装在自己的辅助项目中的NSAssert()中,因此我必须立即处理该问题。

逐渐消退

如果简洁是智慧的源泉,那么布局指南可能是最聪明的,它们全部嵌套在UIKit中。 它非常简单—只是一个普通的老物件,看起来像一个视图,闻起来像一个视图,就像一个视图一样,……不是视图。 这只是一个喜欢“自动布局”的矩形区域。

在很多情况下,这就是开发人员所需要的。 因此,下次您感觉自己要进入间隔视图时,请选择拥抱UILayoutGuide的简单性和安全性。

直到下次time️。


乔丹·摩根(@ JordanMorgan10)| 推特

Jordan Morgan(@ JordanMorgan10)的最新推文。 @buffer上的iOS,@ pluralsight作者,我写了这个…

www.twitter.com


 如果您喜欢本周的帖子,请随时继续并进行NSRecommend(this,where:below);