How to make width of view equal to superview in SwiftUI

Viewed 43853

I have Button

enter image description here

struct ContentView : View {
    var body: some View {
        HStack {
            Button(action: {}) {
                Text("MyButton")
                    .color(.white)
                    .font(Font.system(size: 17))
            }
            .frame(height: 56)
            .background(Color.red, cornerRadius: 0)
        }
    }
}

But I want to pin it to supreview's edges (trailing to superview's trailing and leading). Like this:

enter image description here

HStack doesn't help me, and it's expecting. Fixed frame or width equals UIScree.size are not flexible solutions.

5 Answers

You need to use .frame(minWidth: 0, maxWidth: .infinity) modifier

Add the next code

        Button(action: tap) {
            Text("Button")
                .frame(minWidth: 0, maxWidth: .infinity)
                .background(Color.red)
        }
        .padding(.horizontal, 20)

Padding modifiers will allow you to have some space from the edge.

Keep in mind that the order of modifiers is essential. Because modifiers are functions that are wrapping the view below (they do not change properties of views)

Here's a pure SwiftUI solution where you want to fill the width of the parent but constrain the height to an arbitrary aspect ratio (say you want square images):

        Image("myImage")
            .resizable()
            .scaledToFill()
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .aspectRatio(16.0 / 9.0, contentMode: .fit)

Just replace 16.0 / 9.0 with whatever aspect ratio you want.

I spent about a day trying to figure this out because I didn't want to use GeometryReader or UIScreen.main.bounds (which isn't cross-platform)

Edit: Found an even simpler way.

Simple adding following to your code will make the button extend edge to edge. (You can add padding as well if you want)

.frame(minWidth: 0, maxWidth: .infinity)

The entire Button code will look like this:

struct ContentView : View {
    var body: some View {
        HStack {
            Button(action: {}) {
                Text("MyButton")
                    .color(.white)
                    .font(Font.system(size: 17))
            }
            .frame(minWidth: 0, maxWidth: .infinity)
            .padding(.top, 8)
            .padding(.bottom, 8)
            .background(Color.red, cornerRadius: 0)
        }
    }
}

I found one solution:

var body: some View {
    Button(action: {}) {
            HStack {
                Spacer()
                Text("MyButton")
                    .color(.white)
                    .font(Font.system(size: 17))
                Spacer()
            }
            .frame(height: 56)
            .background(Color.red, cornerRadius: 0)
        }.padding(20)
}

But I'm not sure that it is the best. May be someone will find more elegant solution/

Related