SwiftUI中的布局与对齐指南

论坛 期权论坛 脚本     
匿名技术用户   2021-1-6 05:26   47   0

If I had to name an aspect of SwiftUI development that initially confounded me, it would be alignment guides. As such, I decided to write this article to try to demystify them a little, map out how you can work with them, and indeed make them work for you.

如果我不得不说起最初使我困惑的SwiftUI开发的一个方面,那就是对齐指南。 因此,我决定写这篇文章,试图使它们变得神秘,并阐明如何与他们合作,并确实使它们为您服务。

Alignment guides in SwiftUI are like constraints in UIKit. No, I take that back. They are constraints in SwiftUI — only instead of micromanaging your screen, they macromanage it. You need macro-management for screens these days because they come in all shapes and sizes. However, much like constraints, alignment guides aren’t always that easy to use.

SwiftUI中的对齐指南类似于UIKit中的约束。 不,我拿回去。 它们是SwiftUI中的约束-只是对屏幕进行宏观管理,而不是对其进行微观管理。 如今,您需要对屏幕进行宏管理,因为它们具有各种形状和大小。 但是,就像约束一样,对齐指南并不总是那么容易使用。

The first thing you need to appreciate is the semantics behind the layout mechanism in SwiftUI. The best place to learn about that is Dave Abrahams and John Harper’s talk at 2019 WWDC on the subject. In it, they outline three golden rules for layout:

您需要了解的第一件事是SwiftUI中的布局机制背后的语义。 最好的学习方法是Dave Abrahams和John Harper在2019年WWDC上有关该主题的演讲 。 在其中,他们概述了布局的三个黄金法则:

  • Parent proposes a size for the child.

    父母为孩子建议一个尺寸。
  • Child uses proposal to determine its own size.

    儿童使用提案确定自己的尺寸。
  • Parent uses that size chosen by the child to position said child.

    父母使用孩子选择的尺寸放置孩子。

“What does this have to do with alignment guides?” you may ask. Absolutely everything. To lay out/manage space in SwiftUI, you use containers (ZStack, VStack, and HStack). Containers that are the parents in the semantics above, containers that will organize their siblings using said rules. You can influence these rules with your alignment guides. But wait, there is a snag. Normally, the layout semantics ensure that the layout guides just don’t work (at least for frames, that is). Crazy, I know, but that’s just how the default semantics work.

“这与对齐向导有什么关系?” 你可能会问。 绝对一切。 要在SwiftUI中布局/管理空间,请使用容器(ZStack,VStack和HStack)。 在上述语义中为父级的容器,将使用所述规则组织其兄弟姐妹的容器。 您可以使用对齐指南来影响这些规则。 但是,等等,有一个障碍。 通常,布局语义确保布局指南只是不起作用(至少对于框架而言)。 我知道,这很疯狂,但这就是默认语义的工作方式。

Let’s work through an example. I have a view within which I add a shape (a circle). Here is the code:

让我们来看一个例子。 我有一个视图,可以在其中添加形状(圆形)。 这是代码:

It’s too big, isn’t it? It’s those layout semantics in play. You see, you asked for a circle, didn’t give it a size, and it took as much space as it could. No, we need some rules. Add a ZStack and a frame.

它太大了,不是吗? 正是这些布局语义在起作用。 您看,您要一个圆圈,没有给它一个大小,它占用了尽可能多的空间。 不,我们需要一些规则。 添加一个ZStack和一个框架。

Better, but you didn’t want it in the center. You wanted it at the top, so you check the documentation, add an alignment guide to the frame, and try again. Nothing happens.

更好,但是您不希望它居中。 您想在顶部放置它,因此请查看文档,在框架上添加对齐指南,然后重试。 没发生什么事。

Go back to the picture and look at the red frame. The dot is already at the top of it. Actually, it is at the bottom too as well being on the leading and trailing edges. Sure, you can give it a bigger frame, but then your circle will occupy the whole thing again. It’s a catch-22.

返回图片,并查看红色框。 点已经在它的顶部。 实际上,它也位于底部,也位于前沿和后沿。 当然,您可以给它更大的框架,但是您的圈子将再次占据整个范围。 这是一个陷阱22。

What you need are two frames. Add a second ZStack and a frame to the mix, with an alignment guide on the second frame.

您需要两个框架。 向混合物中添加第二个ZStack和一个框架,并在第二个框架上添加对齐指南。

It’s a super-simple principle that you can apply to get any layout of your choice to work. You just need to start thinking about frames. Apple has defined nine of the most common layouts you might want. Change the alignment you used to a State variable and take a look at your options. Here is an animated GIF to drive the point home. This dancing dot circles around all the options for frame alignment as we change the frame size. Watch it carefully and you’ll see the pattern.

这是一个非常简单的原则,您可以应用该原则来使您选择的任何布局都能正常工作。 您只需要开始考虑框架。 苹果已经定义了您可能需要的最常见的九种布局。 将您使用的对齐方式更改为State变量,然后查看您的选择。 这是一个动画GIF,可用来指示该点。 当我们更改帧大小时,该舞动点会围绕所有用于帧对齐的选项盘旋。 仔细观察,您将看到图案。

Image for post
SwiftUI circle being aligned within changing frame dimensions.
SwiftUI圆在更改的框架尺寸内对齐。

Feels a bit like that famous game of life as I watch it mutate. It is a start, but defining frames for every object within your project and alignment guides… no, we need more. Here is the code behind this dancing bot:

当我看着它变异时,感觉有点像那个著名的生活游戏。 这是一个开始,但是为项目中的每个对象和对齐指南定义框架……不,我们需要更多。 这是该跳舞机器人背后的代码:

Code behind the dancing dot GIF shown.
显示的跳舞点GIF后面的代码。

自定义对齐 (Custom Alignments)

Custom alignments allow you to lay out views relative to each other. To define them, you first need to define some Alignment IDs. This is the template code:

自定义路线允许您相对于彼此布置视图。 要定义它们,您首先需要定义一些对齐ID。 这是模板代码:

With the code for vertical alignment looking like this:

垂直对齐的代码如下所示:

This piece finally links the two already shown:

最后,这篇文章链接了已经显示的两个:

extension Alignment {
static let theAlignment = Alignment(horizontal: .theHorizontalAlignment, vertical: .theVerticalAlignment)
}

OK, now we’ll use the new alignment IDs along with the alignmentGuide view modifier to align two views within the frame relative to each other. The end result looks like this — a couple of dancing bots:

好的,现在我们将使用新的路线ID和alignmentGuide视图修饰符,使框架内的两个视图相对于彼此对齐。 最终结果如下所示:几个跳舞机器人:

Image for post
SwiftUI animation of custom alignments of two views around the center.
围绕中心的两个视图的自定义对齐的SwiftUI动画。

What are we looking at here? Well, the custom alignment has stipulated you need to start at the center and then add your views relative to it and each other. So both circles will stay centered but randomly dance around each other’s leading/trailing, top/bottom edges. As with the other example, we’re changing the size of the frame they are within to help you understand what is happening. Note that the Alignment ID here has been linked to the stack viewModifier — not the frame, as in the first case.

我们在这里看什么? 好吧,自定义对齐方式规定您需要从中心开始,然后添加相对于彼此的视图。 因此,两个圆圈将保持居中,但会围绕彼此的前/后,上/下边缘随机跳舞。 与其他示例一样,我们正在更改它们所在框架的大小,以帮助您了解正在发生的事情。 请注意,此处的Alignment ID已链接到堆栈viewModifier ,而不是第一种情况下的框架。

The code that created this jig looks like this:

创建此夹具的代码如下所示:

Code behind the dancing twin dots.
在跳舞的双点后面编码。

更多自定义视图 (More Custom Views)

We’re not quite finished yet. You see, there is a second version of the alignmentGroup view modifier that is based not on a subscript as shown above but on a computed value:

我们还没有完成。 您会看到, alignmentGroup视图修饰符的第二个版本不是基于上面显示的下标而是基于计算值:

.alignmentGuide(.myHorizontalAlignment, computeValue: {d in viewW})
.alignmentGuide(.theVerticalAlignment, computeValue: {d in viewH})

So the value of the viewW you see in the line above is the value relative to the width of the view it is modifying, and the value of viewH is a value relative to the height of the view being modified. Here is an animated GIF to try to bring that statement to life. In it, we’re varying the viewW and viewH alignments between -64 and 96. In our case, the values’ multiples of size for the circle is 32.

因此,您在上一行中看到的viewW的值是相对于要修改的视图的宽度的值,而viewH的值是相对于要修改的视图的高度的值。 这是一个动画GIF,试图将这种说法变为现实。 在其中,我们正在-64和96之间改变viewWviewH对齐方式。在我们的例子中,圆的值的大小倍数是32。

Image for post
Dancing bots using SwiftUI alignment guides on the Stack View — not the frame.
在Stack View(而不是框架)上使用SwiftUI对齐指南跳舞的机器人。

As you can see, the circles are in fact moving randomly — and madly — across the entire square. There is no placement leading, trailing, top, or bottom here. It’s all coordinates. Note that the alignment modifier is again on the stack and alignment view modifiers.

如您所见,圆圈实际上在整个正方形上随机地(疯狂地)运动。 此处没有放置开头,结尾,顶部或底部的展示位置。 全部都是坐标。 请注意,对齐修改器再次位于堆栈和对齐视图修改器上。

Code behind the custom calculated alignment.
自定义计算的路线后面的代码。

This brings me to the end of this article. I hope I managed to demystify alignments just a little in the process. Keep coding and keep calm.

这使我到本文的结尾。 我希望我在此过程中设法使路线神秘化。 保持编码并保持冷静。

翻译自: https://medium.com/better-programming/layout-in-swiftui-with-alignment-guides-fef821e7e06e

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP