如何让 VStack 填满 SwiftUI 中的屏幕宽度
How to make VStack fill the width of screen in SwiftUI
我正在尝试制作可视化 VStack 属性的 VStack 示例应用程序
但是我的 VStack 无法填满屏幕的宽度
我在网上尝试了很多解决方案(frame modifier、HStack with Spacer、GeometryReader)但它们都不起作用
这是我的代码
父视图
struct LayoutView: View {
@State private var spacing: CGFloat = 0.0
@State private var alignmentIndex = 0
@State private var elementsAmount = 0
private let layout: StackLayout
private let alignments: [String] = [".leading", ".center", ".trailing"]
private let minValue: CGFloat = 0.0
private let maxValue: CGFloat = 100.0
init(_ layout: StackLayout) {
self.layout = layout
}
var body: some View {
NavigationView {
Form {
Section(header: Text("Controls")) {
VStack(alignment: .leading) {
Text("Spacing: \(Int(spacing))").font(.caption)
HStack {
Text("\(Int(minValue))")
Slider(value: $spacing, in: minValue...maxValue, step: 1)
Text("\(Int(maxValue))")
}
}
Picker("alignments", selection: self.$alignmentIndex) {
ForEach(0..<alignments.count) {
Text(self.alignments[[=10=]])
}
}
.pickerStyle(SegmentedPickerStyle())
Stepper("Element's amount: \(elementsAmount)", value: self.$elementsAmount, in: 0...10)
}
Section(header: Text("Canvas")) {
VStackView(spacing: $spacing, alignmentIndex: $alignmentIndex, elementsCount: $elementsAmount)
}
}
.navigationBarTitle(Text(layout.rawValue), displayMode: .inline)
}
}
}
子视图
struct VStackView: View {
@Binding var spacing: CGFloat
@Binding var alignmentIndex: Int
@Binding var elementsCount: Int
private let alignments: [HorizontalAlignment] = [.leading, .center, .trailing]
var body: some View {
VStack(alignment: self.alignments[alignmentIndex], spacing: CGFloat(spacing)) {
ForEach(0..<elementsCount, id: \.self) {
Text("\([=11=])th View")
}
}
}
}
这是结果
您可以将框架的 maxWidth 设置为无穷大 - 这是一种告诉父视图此视图需要它可以获得的所有宽度的方式:
VStack {
//...
} .frame(maxWidth: .infinity)
我猜你可以像这样更新代码
struct VStackView: View {
@Binding var spacing: CGFloat
@Binding var alignmentIndex: Int
@Binding var elementsCount: Int
private let alignments: [HorizontalAlignment] = [.leading, .center, .trailing]
var body: some View {
VStack(alignment: self.alignments[alignmentIndex], spacing: CGFloat(spacing)) {
ForEach(0..<elementsCount, id: \.self) {
Text("\([=10=])th View").frame(maxWidth: .infinity, alignment: Alignment(horizontal: self.alignments[self.alignmentIndex], vertical: .center))
}
}
}
}
我正在尝试制作可视化 VStack 属性的 VStack 示例应用程序
但是我的 VStack 无法填满屏幕的宽度
我在网上尝试了很多解决方案(frame modifier、HStack with Spacer、GeometryReader)但它们都不起作用
这是我的代码
父视图
struct LayoutView: View {
@State private var spacing: CGFloat = 0.0
@State private var alignmentIndex = 0
@State private var elementsAmount = 0
private let layout: StackLayout
private let alignments: [String] = [".leading", ".center", ".trailing"]
private let minValue: CGFloat = 0.0
private let maxValue: CGFloat = 100.0
init(_ layout: StackLayout) {
self.layout = layout
}
var body: some View {
NavigationView {
Form {
Section(header: Text("Controls")) {
VStack(alignment: .leading) {
Text("Spacing: \(Int(spacing))").font(.caption)
HStack {
Text("\(Int(minValue))")
Slider(value: $spacing, in: minValue...maxValue, step: 1)
Text("\(Int(maxValue))")
}
}
Picker("alignments", selection: self.$alignmentIndex) {
ForEach(0..<alignments.count) {
Text(self.alignments[[=10=]])
}
}
.pickerStyle(SegmentedPickerStyle())
Stepper("Element's amount: \(elementsAmount)", value: self.$elementsAmount, in: 0...10)
}
Section(header: Text("Canvas")) {
VStackView(spacing: $spacing, alignmentIndex: $alignmentIndex, elementsCount: $elementsAmount)
}
}
.navigationBarTitle(Text(layout.rawValue), displayMode: .inline)
}
}
}
子视图
struct VStackView: View {
@Binding var spacing: CGFloat
@Binding var alignmentIndex: Int
@Binding var elementsCount: Int
private let alignments: [HorizontalAlignment] = [.leading, .center, .trailing]
var body: some View {
VStack(alignment: self.alignments[alignmentIndex], spacing: CGFloat(spacing)) {
ForEach(0..<elementsCount, id: \.self) {
Text("\([=11=])th View")
}
}
}
}
这是结果
您可以将框架的 maxWidth 设置为无穷大 - 这是一种告诉父视图此视图需要它可以获得的所有宽度的方式:
VStack {
//...
} .frame(maxWidth: .infinity)
我猜你可以像这样更新代码
struct VStackView: View {
@Binding var spacing: CGFloat
@Binding var alignmentIndex: Int
@Binding var elementsCount: Int
private let alignments: [HorizontalAlignment] = [.leading, .center, .trailing]
var body: some View {
VStack(alignment: self.alignments[alignmentIndex], spacing: CGFloat(spacing)) {
ForEach(0..<elementsCount, id: \.self) {
Text("\([=10=])th View").frame(maxWidth: .infinity, alignment: Alignment(horizontal: self.alignments[self.alignmentIndex], vertical: .center))
}
}
}
}