DanubePM
DanubePM

Reputation: 1771

How can I horizontally align two text views so that the leading and trailing edges meet in the middle?

I have two Text views. They are placed next to each other horizontally. How can I align them such that the meeting point of the views is also the center of the container view, regardless of how long either string is?

For example...

This is the first string|Second string.

The pipe here would be the center of the container view. Obviously a simple HStack wouldn't work unless both strings were exactly the same width. (Side note: In my particular use case, the strings won't be so long that they'll need to truncate or line wrap, but that might be useful for other people who have this question).

Upvotes: 3

Views: 1385

Answers (2)

aheze
aheze

Reputation: 30228

To ensure both sides of the pipe are equal width, you can use 2 Spacer()s.

HStack {
    Spacer()
    Divider()
    Spacer()
}

Then, you can overlay text on top of each Spacer().

struct ContentView: View {
    var body: some View {
        HStack {
            Spacer()
            .overlay(
                Text("Hi! This text is in multiple lines. Cool, right?")
                    .fixedSize(horizontal: false, vertical: true) /// allow text wrap
                    .multilineTextAlignment(.trailing) /// align text to right when there are multiple lines
                    .frame(maxWidth: .infinity, alignment: .trailing) /// align text to right when there's 1 line
            )
            
            Divider()
            
            Spacer()
            .overlay(
                Text("Hello!")
                    .fixedSize(horizontal: false, vertical: true)
                    .multilineTextAlignment(.leading)
                    .frame(maxWidth: .infinity, alignment: .leading)
            )
        }
    }
}

Result:

Pipe dividing 2 Texts, both of equal width

Upvotes: 0

jnpdx
jnpdx

Reputation: 52337

You can use a .frame(maxWidth: .infinity) on both Texts, which will end up making them equal widths (50% of the parent).

struct ContentView : View {
    var body: some View {
        VStack {
            HStack(spacing: 2) {
                
                Text("Short")
                    .frame(maxWidth: .infinity, alignment: .trailing)
                    .border(Color.blue)
                Text("Longer. This is longer text....")
                    .lineLimit(1) // remove/change this if you want it to accommodate multiple lines
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .border(Color.green)
            }
        }
    }
}

You can play with the alignment on each depending on your need. Of course, the borders are only there for debugging.

enter image description here

Upvotes: 5

Related Questions