I'm trying to learn SwiftUI and I read this really great article about alignmentGuides and how to align views that are in different containers: https://swiftui-lab.com/alignment-guides/
In my UI, I want to have a checkmark, then a Text() label question on one line (orange), then below that I want the TextField() where they can answer the question (green), and I want the TextField()'s leading to match up with Text() question's leading. Like so:
The above screenshot was generated when I forcibly set the width of the green TextField() with .frame(width: 200)
. I don't want to force the textfield to be a certain size, but when I
Unfortunately, whenever I remove the .frame(width: 200)
...
1) the green TextField() then stretches wider than the screen 2) the outer VStack stretches beyond the screen as well. 3) and the checkmark Image() in the orange HStack is aligned off of the leading side of the screen.
Here is what it looks like without the TextField().frame(width: 200)
, notice the blue outline of the VStack is off both sides of the screen:
Here is the code:
extension HorizontalAlignment {
private enum QuestionAlignment : AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
return d[.leading]
}
}
static let questionAlignment = HorizontalAlignment(QuestionAlignment.self)
}
struct EasyModeQuestion: View {
@Binding var field : String
var body: some View {
VStack(alignment: .questionAlignment) {
Rectangle()
.fill(Color.primary)
.frame(width: 1)
.alignmentGuide(.questionAlignment, computeValue: { d in d[HorizontalAlignment.leading] })
HStack() {
Image(systemName: "checkmark.square")
Text("What is the blah blah blah?")
.alignmentGuide(.questionAlignment, computeValue: { d in d[.leading] })
}.background(Color.orange)
TextFieldRoundedRect(placeholder: "", text: $field)
.alignmentGuide(.questionAlignment, computeValue: { d in d[.leading] })
.background(Color.green)
//.frame(width: 200)
Rectangle()
.fill(Color.primary)
.frame(width: 1)
.alignmentGuide(.questionAlignment, computeValue: { d in d[HorizontalAlignment.leading] })
}
}
}
The two Rectangle() objects above and below are examples from the link at the top of my question, which are supposed to help visualize where the alignment guide is sitting.
When I just go with a basic leading alignment and remove all the alignment guides, then the TextField() returns to an appropriate width: