0

I have a simple view with two texts. Its body is like this:

VStack {
    Text("One")
    Text("Two")
    Text("Three")
}

this produces a view like:

Existing layout

But what I would like is, using only modifiers to the Text views (i.e. no HStack with Spacers), achieve a layout like:

Desired layout

Is this currently possible? I was hoping making the Texts full width somehow and then just using the text alignment would work but haven't figured it out yet.

3 Answers 3

2

Well... as there are no any additional conditions or restrictions, with just added two lines of code

Demo in Preview (blue border is just a selection in code)

demo

    VStack {
        Text("One")
            .frame(maxWidth: .infinity, alignment: .leading)
        Text("Two")
        Text("Three")
            .frame(maxWidth: .infinity, alignment: .trailing)
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Great, thanks! Can you foresee any downsides of using this? i.e. is it "weird" using a frame's alignment for text alignment?
@KerrM, no, actually it is aligned not text (ie, string) but entire view inside provided frame. So if you inter very very long text it fill and wrap in a usual way. Moreover as there is no hardcode change orientation or layout will be handled automatically.
1

Yes, this could be possible. You could define a modifier like:

extension View {
    func horizontalAlignment(_ alignment: HorizontalAlignment) -> some View {
        Group {
            if alignment == .leading {
                HStack {
                    self
                    Spacer()
                }
            } else if alignment == .trailing {
                HStack {
                    Spacer()
                    self
                }
            } else {
                self
            }
        }
    }
}

And use it like:

VStack {
    Text("One")
        .horizontalAlignment(.leading)
    Text("Two")
        .horizontalAlignment(.center)
    Text("Three")
        .horizontalAlignment(.trailing)
}

Of course, multiple approaches are possible.

Comments

1

One approach is to just set the frame:

struct ContentView: View {
    var body: some View {
        VStack {
            Text("One")
                .frame(minWidth: 0,
                       maxWidth: .infinity,
                       alignment: .leading)
            Text("Two")
                .frame(minWidth: 0,
                       maxWidth: .infinity,
                       alignment: .center)
            Text("Three")
                .frame(minWidth: 0,
                       maxWidth: .infinity,
                       alignment: .trailing)

        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.