UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

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?

2      

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

2      

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)

2      

@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.

2      

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.

3      

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

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

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

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.