Home > Back-end >  How to keep an item exactly in the center of an HStack with other items in the HStack
How to keep an item exactly in the center of an HStack with other items in the HStack

Time:12-26

I have two items in an HStack. I want one of them to be perfectly horizontally centered and the other to be on the left side (have an alignment of .leading). Here is my code so far:

HStack {
            Text("1")
                .frame(alignment: .leading)
            
            Text("Hello")
                .frame(alignment: .center)
        }

I have figured out that the .overlay method works. However, I still want Text("Hello") to be aware of the position of Text("1") so that if Text("Hello") were a longer string, it would know not to cover up Text("1"), which is exactly what happens when the .overlay function is used. So I'm wondering if there are any other solutions.

CodePudding user response:

You can add one more Text view inside HStack as hidden which have the same content as your left align text view along with Spacer. Something like this.

HStack {
    Text("1")
    Spacer()
    Text("Good Morning, Hello World. This is long message")
        .multilineTextAlignment(.center)
    Spacer()
    Text("1") // Set the same content as left aligned text view
        .hidden()
 }
 .padding(.horizontal)

Preview

CodePudding user response:

Not sure if it's the best way, but you can use a GeometryReader to get the screen width and skip the first half. To place the text exactly in the center, you should also calculate the width of the text. you can use a simple extension to get the size of your text:

extension String {
public func size(withFont font: UIFont) -> CGSize {
    (self as NSString).size(withAttributes: [.font: font])
}

}

Here is the example code:

GeometryReader { geo in
            
            HStack {
                Spacer()
                    .frame(width: (geo.size.width - "center".size(withFont: UIFont.systemFont(ofSize: 18)).width) / 2)
                HStack {
                    Text("center")
                    Text("another")
                }
            }
            
        }
  • Related