Make a VStack fill the width of the screen in SwiftUI

前端 未结 14 1702
失恋的感觉
失恋的感觉 2020-12-07 16:58

Given this code :

import SwiftUI

struct ContentView : View {
    var body: some View {
        VStack(alignment: .leading) {
            Text(\"Title\")
            


        
14条回答
  •  臣服心动
    2020-12-07 17:43

    There is a better way!

    To make the VStack fill the width of it's parent you can use a GeometryReader and set the frame. (.relativeWidth(1.0) should work but apparently doesn't right now)

    struct ContentView : View {
        var body: some View {
            GeometryReader { geometry in
                VStack {
                    Text("test")
                }
                    .frame(width: geometry.size.width,
                           height: nil,
                           alignment: .topLeading)
            }
        }
    }
    

    To make the VStack the width of the actual screen you can use UIScreen.main.bounds.width when setting the frame instead of using a GeometryReader, but I imagine you likely wanted the width of the parent view.

    Also, this way has the added benefit of not adding spacing in your VStack which might happen (if you have spacing) if you added an HStack with a Spacer() as it's content to the VStack.

    UPDATE - THERE IS NOT A BETTER WAY!

    After checking out the accepted answer, I realized that the accepted answer doesn't actually work! It appears to work at first glance, but if you update the VStack to have a green background you'll notice the VStack is still the same width.

    struct ContentView : View {
        var body: some View {
            NavigationView {
                VStack(alignment: .leading) {
                    Text("Hello World")
                        .font(.title)
                    Text("Another")
                        .font(.body)
                    Spacer()
                    }
                    .background(Color.green)
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
                    .background(Color.red)
            }
        }
    }
    

    This is because .frame(...) is actually adding another view to the view hierarchy and that view ends up filling the screen. However, the VStack still does not.

    This issue also seems to be the same in my answer as well and can be checked using the same approach as above (putting different background colors before and after the .frame(...). The only way that appears to actually widen the VStack is to use spacers:

    struct ContentView : View {
        var body: some View {
            VStack(alignment: .leading) {
                HStack{
                    Text("Title")
                        .font(.title)
                    Spacer()
                }
                Text("Content")
                    .lineLimit(nil)
                    .font(.body)
                Spacer()
            }
                .background(Color.green)
        }
    }
    

提交回复
热议问题