1

Here is a simple code that produces a strange top alignment and shrunk text of the second element inside ZStack.

BUT if you change the second text a bit (replace text2 by text2Alt1 or by text2Alt2) making it longer or shorter everything becomes correct.

What is the reason for this behavior?

struct VCardView: View {
    let text: String
    let color: UIColor
    
    var body: some View {
        VStack {
            Rectangle()
                .fill(Color(self.color))
                .frame(idealWidth: 800, idealHeight: 500)
                .aspectRatio(contentMode: .fit)

            Text(self.text)
        }
    }
}

struct ContentView: View {
    var body: some View {
        ZStack(alignment: .topLeading) {
            VCardView(text: text1, color: .blue)
                .frame(width: 180, height: nil)
                .alignmentGuide(.leading) { _ in 180 }
                .alignmentGuide(.top) { _ in 0 }
            
            //Replace text2 by text2Alt1 or text2Alt2 here:
            VCardView(text: text2, color: .green)
                .frame(width: 180, height: nil)
                .alignmentGuide(.leading) { _ in 0 }
                .alignmentGuide(.top) { _ in 0 }
        }
    }
    
    let text1 = "1Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidu!"
    
    let text2 = "2Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis nat!"
    
    
    let text2Alt1 = "2Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. C"
    
    let text2Alt2 = "2Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis nat! Cum sociis nat!"
}

Also, you could replace Rectangle() by Image() with appropriate proportions because it was the initial state. Rectangle with the ideal size is just for demonstration.

Here I use ZStack with explicit alignment guides (not HStack) because it's a part of another library. It is essential.

XCode 11.5 iOS 13.5 iPhone SE 2020

Bug looks like this:

Expected layout:

2 Answers 2

1

I've seen such Text truncation problems often in SwiftUI. The workaround which most of the time helps: ensure that Text is allowed to adjust it's font size automatically using the minimumScaleFactor modifier.

By modifying VCardView

Text(self.text)
    .minimumScaleFactor(0.5)

The misalignment problem disappears for all possible text values (text1, text2, text2Alt1 and text2Alt2).

The resulting text does not look scaled at all. Everything fits nicely. I do not have a good explanation, but I think if you tell SwiftUI that your Text is not 100% rigid/stiff, it performs better in calculating the elements extents.

Perhaps it is a SwiftUI bug, but I was always OK with this minimumScaleFactor workaround as it hadn't negatively impacted my results.

Sign up to request clarification or add additional context in comments.

Comments

0

it doesn't look like a ZStack problem. Try to remove .aspectRatio(contentMode: .fit) from Rectangle() in VCardView.

For rectangle proportion check something like this.

1 Comment

The idea is to save proportions based on the intrinsic size of the Rectange() view and fit to the parent view (limited by .frame(width: 180, height: nil)). Replace Rectangle() by Image() and remove frame(idealWidth: idealHeight:) for example. The result is the same and GeometryReader can't help you to read an image intrinsic size.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.