migueljuan
migueljuan

Reputation: 469

Scrollview doesn't scroll past views with an offset

To solve a much more complicated problem, I created the following simple test project:

struct ContentView: View {
    var body: some View {
        ScrollView {
            ZStack {
                ForEach(0..<50) { index in
                    Text("Test \(index)")
                        .offset(x: 0, y: CGFloat(index * 20))
                }
            }
        }
    }
}

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

This draws 50 Text views inside a ZStack, each one with a larger y offset, so that they are drawn down past the visible part of the screen:

enter image description here

The whole thing is wrapped inside of a ScrollView, so I expect that I should be able to scroll down to the last view.

However, it doesn't scroll past Test 26.

How can I arrange views inside of a ZStack by assigning offsets and update the ScrollView's contentSize?

Upvotes: 1

Views: 718

Answers (2)

Asperi
Asperi

Reputation: 257493

If I understood your intention correctly then you don't need offset in this scenario at all (SwiftUI works differently)

    ScrollView {
        VStack {
            ForEach(0..<50) { index in
                Text("Test \(index)")   // << use .padding if needed
            }
        }
    }

Note: The offset does not change view layout, view remains in the same place where it was created, but rendered in place of offset; frames of other views also not affected. Just be aware.

Upvotes: 1

YodagamaHeshan
YodagamaHeshan

Reputation: 6500

The content size is calculated by the size of the view inside the ScrollView. So that only thing we can do is to change that view size.

By default VStack size is the total size (actual view sizes) of views inside it.

As well as we can use frame() to change the size in this case. check apple document

Since VStack arrange view in the middle we can align it to the .top.

struct ContentView: View {
    var body: some View {
        ScrollView() {
            VStack {
                ForEach(0..<50) { index in
                    Text("Test \(index)")
                        .offset(x: 0, y: CGFloat(index * 20))
                }
            }
            .frame( height: 2000, alignment: .top) //<=here
            .border(Color.black)
        }
    }
}

Upvotes: 1

Related Questions