olejnjak
olejnjak

Reputation: 1363

Make ScrollView content fill its parent in SwiftUI

I'd love to build a scrolling screen, so I wanted to embed it ScrollView. But I am not able to achieve it the view just shrinks to its compressed size. Let's say that I want the ScrollView to scroll vertically so I'd love the content to match scrollView's width. So I use such preview:

struct ScrollSubview_Previews : PreviewProvider {
    static var previews: some View {
        func textfield() -> some View {
            TextField(.constant("Text")).background(Color.red)
        }

        return Group {
            textfield()
            ScrollView {
                textfield()
            }
        }
    }
}

But it ends with result like this:

enter image description here

Upvotes: 35

Views: 66868

Answers (7)

Hoang Nguyen
Hoang Nguyen

Reputation: 442

A simple way for you, using frame(maxWidth: .infinity)

ScrollView(.vertical) {
    VStack {
        ForEach(0..<100) {
            Text("Item \($0)")
        }
    }
    .frame(maxWidth: .infinity)
}

Upvotes: 35

Artjom Spole
Artjom Spole

Reputation: 181

Scroll view content will expand to available size.

GeometryReader { geo in
            ScrollView(.vertical) {
                YourView().frame(
                    minWidth: geo.size.width,
                    minHeight: geo.size.height
                )
            }
        }

Upvotes: 7

Actually you don't need GeometryReader anymore. ScrollView has been refactored in Xcode beta 3. Now you can declare that you have a .horizontal or .vertical ScrollView. This makes the ScrollView behave like it should, like any normal View protocol.

Ex:

ScrollView(.horizontal, showsIndicators: false) {
    HStack {
        ForEach((1...10).reversed()) {
            AnyViewYouWant(number: $0)
        }
    }
}

This will result in a view with the width of its parent scrolling horizontally. The height will be defined by the ScrollView's subviews height.

Upvotes: 5

Amisha Italiya
Amisha Italiya

Reputation: 246

  • You can also done this using extra HStack and space.

    ScrollView(.vertical) {
        HStack {
            VStack {
                 ForEach(0..<100) {
                    Text("Item \($0)")
                 }
             }
             Spacer()
         }
    }
    

Upvotes: 3

xxcat
xxcat

Reputation: 137

It's a known issue existing also in beta 2 - check the Apple's Xcode 11 release notes here ⬇️ https://developer.apple.com/documentation/xcode_release_notes/xcode_11_beta_2_release_notes.

The workaround mentioned by Apple themselves is to set fixed frame for ScrollView inside element. In that case I suggest to use GeometryReader for fix screen width, height is automatically fit to content.

For example if you need to fit the ScrollView's content to screen width you can something like:

return GeometryReader { geometry in
     Group {
         self.textfield()
         ScrollView {
             self.textfield()
                 .frame(width: geometry.size.width)
         }
     }
 }

Upvotes: 10

ielyamani
ielyamani

Reputation: 18591

Here is a trick: introduce a HStack that only has one Spacer:

return Group {
        HStack {
            Spacer()
        }
        textfield()
        ScrollView {
            textfield()
        }
    }

Upvotes: 14

Argas
Argas

Reputation: 1537

PreviewProvider is just about your Canvas (rendering view).

if you want to place text into ScrollView you should create your View

struct MyViewWithScroll : View {
    var body: some View {
        ScrollView {
            Text("Placeholder")
        }
    }
}

And after that, render your MyViewWithScroll in Canvas (window with iPhone from the right side of code editor)

#if DEBUG
struct MyViewWithScroll_Previews : PreviewProvider {
    static var previews: some View {
        MyViewWithScroll()
    }
}
#endif

Upvotes: -4

Related Questions