SwiftUI中的约束是什么?

51

SwiftUI中的约束现在发生了什么?View类型是否会自动适应更大的设备等,或者我们需要采取什么措施?

3个回答

85

安息,约束!

SwiftUI 不使用布局约束。 UIKit 仍然存在,没有被弃用且完全可用,因此如果您继续使用传统方法,可以使用任意数量的约束。

但是,如果您选择使用 SwiftUI → 安息,约束!

墓碑上写着“RIP Constraints”

将视图与其他视图对齐的核心概念是使用堆栈:

如果您想叠加视图(即将一个视图放在另一个视图上方),可以使用

View 协议本身(所有视图类型神秘地符合该协议)有大量名为 修饰符 的函数,您可以使用这些函数来自定义视图的布局。


示例

以下是一些示例,说明如何使用这些修饰符实现特定的布局,与使用约束相比:

1. 纵横比

不要使用约束来设置视图的纵横比,而是使用 aspectRatio 修饰符:

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 修饰符来指定其宽度:

UIKit 中,您可以将视图排列在水平堆栈中,并在它们之间添加一个spacer,并使用frame修饰符来指定其宽度:

HStack {
    view1
    Spacer()
        .frame(width: 30)
    view2
}

3. 等宽

这是更加复杂的部分。你不能再指定两个视图有相同的宽度了。如果它们在同一垂直堆栈中(即在垂直线上对齐),那就好说:只需将 contentMode 设置为 .fill ,通过设置堆栈视图的宽度来控制实际宽度 → 完成任务 ✅。但如果它们不在一个垂直堆栈中(例如,当它们在水平堆栈中时),您必须找到其他方法来表达它们之间的关系。具体实现取决于您要描述的具体布局。


SwiftUI 的一般思想是尽可能保持视图的简洁性并进行组合。这里有一个小的权衡:您需要付出在不同视图层次结构中视图之间的 "约束" 实现变得更加冗长的代价,而最终获得的收益是布局是声明性的,并且创建最常见用户界面的代码大大简化。


屏幕适配 / 响应式设计

默认情况下,自定义视图会填充整个可用空间,这意味着最上面的视图会自动占据整个屏幕,而不管实际屏幕大小。您可以使用修饰符更改此行为。


1
@Sulthan 不一定。SwiftUI 是一个专门的框架,就像 UIKit 一样。不过,由于 SwiftUI 目前还处于测试阶段,它仍然使用了很多 UIKit 的组件,所以它常常被认为是一个高级别的 UIKit API。但是最终 SwiftUI 将会完全独立于 UIKit,有自己的方法论。 - trndjc
我该如何在 VStack 上将 contentMode 设置为 .fill?找不到相应的修饰符。 - SwiftiSwift
1
@jsbeginnerNodeJS 使用:.aspectRatio(contentMode: .fill) - Frakcool
1
我认为SwiftUI仍然在某些方面(例如上下文菜单)使用约束。https://dev59.com/trfna4cB1Zd3GeqP2f26 - wshamp
1
如果让两个水平排列的按钮拥有相同的宽度都很困难,我不认为我会同意“创建最常见用户界面的代码被大大简化”的说法。 - WolfLink
显示剩余2条评论

10

它仍然有限制,在WWDC示例中,我们看到了HStackVStack,它们看起来像UIStackView,所以我猜它只是剪裁到边缘。您仍然可以向视图添加填充,因此,如果您想将UILabel(文本)约束到左侧10pt,则可以执行以下操作:

Text("Hello World").padding(EdgeInsets(top: 0, leading: 10, bottom: 0, trailing: 0))

0

约束已经非常好了,这很棒,但是有一种叫做.padding()的东西,它可以通过在左侧放置类似于前导参数的东西来实现某种约束外观,使图像靠近视图的一侧。

struct ContentView: View {
   var body: some View {
      Image("x")
         .padding(.leading)
 
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接