0
votes

I'm trying to align text in two different HStacks but having difficulties getting the second (shorter length) one to align with the first HStack. I've tried using .frame(minWidth:0, maxWidth: .infinity) and Spacer()'s but can't find a solution. Is this possible at all?

struct ContentView: View {
var body: some View {
    VStack(alignment: .leading) {
        HStack {
            Spacer()
            Text("Lorem ipsum dolor")
                .font(.system(size: 22, weight: .ultraLight, design: .rounded))
            Spacer()
        }.padding()
        .overlay(
            Rectangle()
                .stroke(Color(#colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)), style: StrokeStyle(lineWidth: 0.5, dash: [5.0])))
       
        
        HStack {
            Spacer()
            Text("Lorem ipsum")
                .font(.system(size: 22, weight: .ultraLight, design: .rounded))
            Spacer()
        }.padding()
        .overlay(
            Rectangle()
                .stroke(Color(#colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)), style: StrokeStyle(lineWidth: 0.5, dash: [5.0])))
    }
  }
}

What I currently have

I attempted to use a HorizontalAlignment guide, but they became off-centred:

struct ContentView: View {
var body: some View {
    VStack(alignment: .controlLeadingEdge) {
        HStack {
            Text("Lorem ipsum dolor")
                .font(.system(size: 22, weight: .ultraLight, design: .rounded))
                .alignmentGuide(.controlLeadingEdge, computeValue: { d in d[HorizontalAlignment.leading] })
        }.padding()
        .frame(minWidth: 0, maxWidth: 300)
        .overlay(
            Rectangle()
                .stroke(Color(#colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)), style: StrokeStyle(lineWidth: 0.5, dash: [5.0])))
        
        HStack {
            Text("Lorem ipsum")
                .font(.system(size: 22, weight: .ultraLight, design: .rounded))
                .alignmentGuide(.controlLeadingEdge, computeValue: { d in d[HorizontalAlignment.leading] })
        }.padding()
        .frame(minWidth: 0, maxWidth: 300)
        .overlay(
            Rectangle()
                .stroke(Color(#colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)), style: StrokeStyle(lineWidth: 0.5, dash: [5.0])))
        
    }
 }
}

extension HorizontalAlignment {
private enum ControlAlignment: AlignmentID {
    static func defaultValue(in context: ViewDimensions) -> CGFloat {
        return context[HorizontalAlignment.controlLeadingEdge]
    }
}
static let controlLeadingEdge = HorizontalAlignment(ControlAlignment.self)
}

HorizontalAlignment Attempt

1
How do you want it aligned? Do you want the longest one centered and the other aligned to the leading edge of the longest? Is the second one always shorter?vacawama
@vacawama I wanted to have the shortest one aligned to the leading edge of the longest. Yes that's correct, the second one will also be shorter. Thanksuser2047296

1 Answers

1
votes

Here is one way to do it:

Repeat the first text, give it .opacity(0) and put it in a ZStack with .leading alignment

struct ContentView: View {
    var body: some View {
        let firstText = Text("Loren ipsum dolor")
        let secondText = Text("Loren ipsum")
        
        VStack(alignment: .leading) {
            HStack {
                Spacer()
                firstText
                    .font(.system(size: 22, weight: .ultraLight, design: .rounded))
                Spacer()
            }.padding()
            .overlay(
                Rectangle()
                    .stroke(Color(#colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)), style: StrokeStyle(lineWidth: 0.5, dash: [5.0])))
            
            HStack {
                Spacer()
                ZStack(alignment: .leading) {
                    firstText.opacity(0)
                    secondText
                }
                .font(.system(size: 22, weight: .ultraLight, design: .rounded))
                Spacer()
            }.padding()
            .overlay(
                Rectangle()
                    .stroke(Color(#colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)), style: StrokeStyle(lineWidth: 0.5, dash: [5.0])))
        }
    }
}