SwiftUI 中的约束是什么?
What's with Constraints in SwiftUI?
SwiftUI
中的 约束 现在发生了什么? View
类型会自动适应更大的设备等吗?或者我们应该怎么做?
它仍然有约束,在 WWDC 示例中我们看到 HStack
和 VStack
,看起来像 UIStackView
,所以我猜它只是剪到边缘。你仍然可以在视图中添加填充,所以如果你想要约束一个 UILabel
(Text) 10pt to left 你做这样的事情:
Text("Hello World").padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 0))
安息吧,约束!
SwiftUI 不使用布局约束。 UIKit 仍然存在,它没有被弃用并且功能齐全,所以如果您继续使用经典方法,您可以使用任意数量的约束。
但是,如果您选择使用 SwiftUI → 安息吧,约束!
使视图彼此对齐的核心概念是使用堆栈:
如果你想叠加视图(即将一个视图放在另一个视图之上),你可以使用
View protocol itself () 有大量称为 modifiers 的函数,您可以使用它们来自定义视图的布局。
例子
下面是一些示例,与使用约束相比,您如何使用这些修饰符实现特定布局:
1。纵横比
而不是
view.widthAnchor.constraint(equalTo: view.heightAnchor, multiplier: 2)
在 UIKit 你会写
view
.aspectRatio(2, contentMode: .fit)
在 SwiftUI.
2。视图间距
而不是
view2.leadingAnchor.constraint(equalTo: view1.leadingAnchor, constant: 8)
在 UIKit 中,您可以在水平堆栈中排列视图并在它们之间添加 spacer 并添加 frame
修饰符以指定其宽度:
HStack {
view1
Spacer()
.frame(width: 30)
view2
}
3。等宽
这就是它变得更加复杂的地方。您不能再指定两个视图具有相同的宽度。如果它们在同一个垂直堆栈中(即在垂直线上对齐),很好:只需将 contentMode
设置为 .fill
并通过设置堆栈视图的宽度来控制实际宽度 → 任务完成。 ✅ 但如果它们不是(例如,当它们水平堆叠时),您必须找到其他方式来表达它。实际实施将取决于您要描述的具体布局。
SwiftUI 的总体思路是保持视图尽可能小并组合它们。这里有一点 trade-off:你付出的代价是 "constraints" 不同视图层次结构中的视图之间的实现变得更加冗长,最终的收获是布局是声明式的,并且创建的代码最通用用户界面得到极大简化。
屏幕适配/响应
默认情况下,自定义视图会填满整个可用 space,这意味着最顶层的视图会自动填满整个屏幕 – 无论实际屏幕尺寸如何。您可以使用 修饰符 来更改该行为。
约束已经很好地消失了,这很好,但是有一个叫做 .padding() 的东西,它可以通过将它放在左侧来做一些约束的外观,比如让图像开始的前导参数在视图的一侧
struct ContentView: View {
var body: some View {
Image("x")
.padding(.leading)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
SwiftUI
中的 约束 现在发生了什么? View
类型会自动适应更大的设备等吗?或者我们应该怎么做?
它仍然有约束,在 WWDC 示例中我们看到 HStack
和 VStack
,看起来像 UIStackView
,所以我猜它只是剪到边缘。你仍然可以在视图中添加填充,所以如果你想要约束一个 UILabel
(Text) 10pt to left 你做这样的事情:
Text("Hello World").padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 0))
安息吧,约束!
SwiftUI 不使用布局约束。 UIKit 仍然存在,它没有被弃用并且功能齐全,所以如果您继续使用经典方法,您可以使用任意数量的约束。
但是,如果您选择使用 SwiftUI → 安息吧,约束!
使视图彼此对齐的核心概念是使用堆栈:
如果你想叠加视图(即将一个视图放在另一个视图之上),你可以使用
View protocol itself (
例子
下面是一些示例,与使用约束相比,您如何使用这些修饰符实现特定布局:
1。纵横比
而不是
view.widthAnchor.constraint(equalTo: view.heightAnchor, multiplier: 2)
在 UIKit 你会写
view
.aspectRatio(2, contentMode: .fit)
在 SwiftUI.
2。视图间距
而不是
view2.leadingAnchor.constraint(equalTo: view1.leadingAnchor, constant: 8)
在 UIKit 中,您可以在水平堆栈中排列视图并在它们之间添加 spacer 并添加 frame
修饰符以指定其宽度:
HStack {
view1
Spacer()
.frame(width: 30)
view2
}
3。等宽
这就是它变得更加复杂的地方。您不能再指定两个视图具有相同的宽度。如果它们在同一个垂直堆栈中(即在垂直线上对齐),很好:只需将 contentMode
设置为 .fill
并通过设置堆栈视图的宽度来控制实际宽度 → 任务完成。 ✅ 但如果它们不是(例如,当它们水平堆叠时),您必须找到其他方式来表达它。实际实施将取决于您要描述的具体布局。
SwiftUI 的总体思路是保持视图尽可能小并组合它们。这里有一点 trade-off:你付出的代价是 "constraints" 不同视图层次结构中的视图之间的实现变得更加冗长,最终的收获是布局是声明式的,并且创建的代码最通用用户界面得到极大简化。
屏幕适配/响应
默认情况下,自定义视图会填满整个可用 space,这意味着最顶层的视图会自动填满整个屏幕 – 无论实际屏幕尺寸如何。您可以使用 修饰符 来更改该行为。
约束已经很好地消失了,这很好,但是有一个叫做 .padding() 的东西,它可以通过将它放在左侧来做一些约束的外观,比如让图像开始的前导参数在视图的一侧
struct ContentView: View {
var body: some View {
Image("x")
.padding(.leading)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}