BLACK FRIDAY SALE: Save big on all my Swift books and bundles! >>

Limiting List or Form to size of content

Forums > SwiftUI

By default, Lists and Forms seem to take as much space as they can. For example:

struct CardView: View {
    let text: String

    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 25)
                .frame(width: 200, height: 150)
                .foregroundColor(.gray)
            Text(text)
                .font(.largeTitle)
        }
    }
}

struct ListView: View {
    var body: some View {
        List {
            ForEach((1...3), id: \.self) {
                Text("Item \($0)")
            }
        }
    }
}

struct FormView: View {
    var body: some View {
        Form {
            ForEach((1...3), id: \.self) {
                Text("Item \($0)")
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            //ListView()
            // FormView()
            CardView(text: "Card 1")
            CardView(text: "Card 2")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

If just the two cards are shown, they center on the screen, but if a List or Form is above a card, the card is pushed to the bottom of the screen, and Spacer()s seem to have no effect.

Is there any built-in SwiftUI style option for Lists or Forms that set them to to use only the space required by their content?

   

Quick answer NO.

List and Form will take the whole available space that is left after any child view has it's available space.

You can put "static" items in a list or form. This way the CardView are just below the list items

struct ListView: View {
    var body: some View {
        List {
            ForEach((1...3), id: \.self) {
                Text("Item \($0)")
            }

            VStack {
                HStack {
                    Spacer()
                    CardView(text: "Card 1")
                    Spacer()
                }
                HStack {
                    Spacer()
                    CardView(text: "Card 2")
                    Spacer()
                }
            }
        }
    }
}

I do the HStack Spacer Content Spacer if I want a Button in the List/Form

   

A way to restrict the size of the content view would be to specify a frame with a maximum height, for example

List {
    ForEach((1...5), id: \.self) {
        Text("Item \($0)")
    }
}
.frame(maxHeight: 200)

   

@Greenamberred Thanks, but restricting the frame of the Form/List would be counter to letting SwiftUI manage the layout for different font sizes etc that the user might choose.

Unless the frame size was set using some calcuated value for the current height of the row (like here), but that's what I was trying to avoid/wondering if SwiftUI had some option to do that dynamically.

@NigelGee Thanks, that's an interesting solution. A bit of a workaround in some ways, but might work. I'll play with it.

   

I understand. Sometimes, though, you need to give SwiftUI a helping hand. It won't know that some areas can be smaller. It is doing a balancing act between all the views, unless you give it some hint.

You could also consider .layoutPriority() and GeometryReader.

1      

As @Greenamberred said. GeometryReader is a good approach to adapt your views dynamically to screen size.

   

Hacking with Swift is sponsored by RevenueCat

SPONSORED In-app subscriptions are a pain to implement, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app. Oh, and it's free if your app makes less than $10k/mo.

Learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.