Home > Net >  SwiftUI layout - How to align center correctly?
SwiftUI layout - How to align center correctly?

Time:11-05

I'm wondering how could I align correctly the second Text at the middle because in this example it depends of the Texts to the left and right.

I'd love to have the Text("Not really in the middle") perfectly aligned to the center.

HStack {
    Text("Left")
    Spacer()
    Text("Not really in the middle")
    Spacer()
    Text("Right but long")
}

Maybe, there's a modifier for it that I don't know about? Because using a Grid for this part seems to be exaggerated? Thanks!

CodePudding user response:

The easiest way I know of is to use a ZStack:

ZStack {
    HStack {
        Text("Left")

        Spacer()

        Text("Right but long")
    }

    Text("In the middle")
}

However, this has the problem that it doesn't prevent the texts from overlapping. To solve that is much more complicated; here's one potential solution using GeometryReader:

struct ExampleView: View {
    @State var totalWidth: CGFloat = 0
    @State var leftWidth: CGFloat = 0
    @State var rightWidth: CGFloat = 0
    
    var middleWidth: CGFloat { totalWidth - 2 * max(leftWidth, rightWidth) }
    
    var body: some View {
        ZStack {
            GeometryReader(content: updateTotalWidth)
            
            HStack {
                Text("Left")
                    .overlay(GeometryReader(content: updateLeftWidth))
                
                Spacer()
                    .frame(width: (totalWidth - middleWidth) / 2 - leftWidth)
                
                Text("In the middle but longer")
                    .frame(width: middleWidth)
                
                Spacer()
                    .frame(width: (totalWidth - middleWidth) / 2 - rightWidth)
                
                Text("Right but long")
                    .overlay(GeometryReader(content: updateRightWidth))
            }
        }
    }
    
    private func updateTotalWidth(_ proxy: GeometryProxy) -> some View {
        self.totalWidth = proxy.size.width
        return EmptyView()
    }
    
    private func updateLeftWidth(_ proxy: GeometryProxy) -> some View {
        self.leftWidth = proxy.size.width
        return EmptyView()
    }
    
    private func updateRightWidth(_ proxy: GeometryProxy) -> some View {
        self.rightWidth = proxy.size.width
        return EmptyView()
    }
}
  • Related