Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI views in VStack are overlapping each other

Tags:

swiftui

I have two views in a VStack. All looks fine until I try to enlarge the font in accessibility setting. Then for some reason the stack is not expanding to accommodate both views. Instead it is pushing one view on top of another. See below. enter image description here

How can I align these correctly? Below is my code.

 var body: some View {
    VStack(spacing: 10) {
        Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.")
            .fixedSize(horizontal: false, vertical: true)
            .padding()

        GeometryReader { geometry in
            VStack(spacing: 0) {
                Image("tmp")
                    .resizable()
                    .scaledToFill()
                    .frame(width: geometry.size.width * 0.88)

                VStack(spacing: 10) {
                    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
                        .frame(width: geometry.size.width * 0.8, alignment: .leading)
                        .fixedSize(horizontal: false, vertical: true)

                    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
                        .frame(width: geometry.size.width * 0.8, alignment: .leading)
                        .fixedSize(horizontal: false, vertical: true)

                    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
                        .frame(width: geometry.size.width * 0.8, alignment: .leading)
                        .fixedSize(horizontal: false, vertical: true)
                }
                .padding()
                .background(
                    Rectangle()
                        .fill(Color.white)
                )
            }
            .cornerRadius(10)
            .edgesIgnoringSafeArea(.all)
        }
        .scaledToFit()
        .shadow(color: .gray, radius: 10, x: 5, y: 5)
        .scaledToFill()

        Spacer()
    }
    .background(Rectangle()
        .fill(Color.gray)
        .scaledToFill())
}
like image 289
user1366265 Avatar asked Oct 29 '25 12:10

user1366265


1 Answers

The Issue:

The issue of overlapping is with this section:

    .scaledToFit() // Not needed
    .shadow(color: .gray, radius: 10, x: 5, y: 5)
    .scaledToFill() // Not needed

The Answer:

You don't need neither scaledToFit nor scaledToFill there.


Visualizing the Issue:

using scaledToFill:

scaledToFill

using scaledToFit:

scaledToFit

See blue borders? Thats the issue.


Some Tips:

  1. There is no need to create a dummy Rectangle for background color. .background modifier can accept a color directly like:
.background(Color.gray)
  1. You can ignore safe area only for background modifier like:
.background(Color.gray.edgesIgnoringSafeArea(.all))
  1. Don't repeat modifiers! group them together and apply once like:
Group {
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
}
.frame(width: geometry.size.width * 0.8, alignment: .leading)
.fixedSize(horizontal: false, vertical: true)
  1. Multiplying width in a float number can cause misaligned images. So always round the result like:
(geometry.size.width * 0.88).rounded(.down)

Result:

Image:

Result

Refactored Code:

var body: some View {
    VStack(spacing: 10) {
        Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.")
            .padding()

        GeometryReader { geometry in
            VStack(spacing: 0) {
                Image("tmp")
                    .resizable()
                    .scaledToFill()
                    .frame(width: (geometry.size.width * 0.88).rounded(.down))

                VStack(spacing: 10) {
                        Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
                        Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
                        Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit")
                }
                .frame(width: (geometry.size.width * 0.8).rounded(.down), alignment: .leading)

                .padding()
                .background(Color.white)
            }
            .cornerRadius(10)
        }
        .shadow(color: .gray, radius: 10, x: 5, y: 5)
        Spacer()
    }
    .background(Color.gray.edgesIgnoringSafeArea(.all))
}
like image 161
Mojtaba Hosseini Avatar answered Nov 01 '25 13:11

Mojtaba Hosseini



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!