Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI: Why is the content of this ScrollView misplaced?

Tags:

swift

swiftui

The below sample code should produce a grid of RoundedRectangles inside a ScrollView. With Buttons in the NavigationBar, you can change the number of rows and columns. It works the best on the iPad, because of its bigger screen.

When you run this code, you will see (or at least, I saw) that the content of the ScrollView is not centered well. When you add some rows and columns, you can't see the topmost and leftmost ones and at the bottom and at the right there is some blank space.

Do more people experience this problem? Has anybody found a solution? Does someone know an alternative way to create a scrollable grid with flexible width and height?

import SwiftUI

struct ContentView: View {
    @State var x: Int = 5
    @State var y: Int = 5
    var body: some View {
        NavigationView {
            ScrollView([.horizontal, .vertical]) {
                VStack(spacing: 8) {
                    ForEach(0 ..< self.y, id: \.self) { yCoor in
                        HStack(spacing: 8) {
                            ForEach(0 ..< self.x, id: \.self) { xCoor in
                                RoundedRectangle(cornerRadius: 10)
                                    .frame(width: 120, height: 120)
                                    .foregroundColor(.orange)
                                    .overlay(Text("(\(xCoor), \(yCoor))"))
                            }
                        }
                    }
                }
                .border(Color.green)
            }
            .border(Color.blue)
            .navigationBarTitle("Contents of ScrollView misplaced", displayMode: .inline)
            .navigationBarItems(
                leading: HStack(spacing: 16) {
                    Text("x:")
                        .bold()
                    Button(action: { if self.x > 0 { self.x -= 1 } }) {
                        Image(systemName: "minus.circle.fill")
                            .imageScale(.large)
                    }
                    Button(action: { self.x += 1 }) {
                        Image(systemName: "plus.circle.fill")
                            .imageScale(.large)
                    }
                },
                trailing: HStack(spacing: 16) {
                    Text("y:")
                        .bold()
                    Button(action: { if self.y > 0 { self.y -= 1 } }) {
                        Image(systemName: "minus.circle.fill")
                            .imageScale(.large)
                    }
                    Button(action: { self.y += 1 }) {
                        Image(systemName: "plus.circle.fill")
                            .imageScale(.large)
                    }
                }
            )
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}
like image 452
cbjeukendrup Avatar asked Nov 20 '25 15:11

cbjeukendrup


1 Answers

Some workaround is to separate scroll view for vertical and horizontal axis.

import SwiftUI

struct Row: View {
    var _y: Int
    var x: Range<Int>
    var body: some View {
        HStack {
            ForEach(x) { _x in
                RoundedRectangle(cornerRadius: 10).tag(_x)
                    .frame(width: 120, height: 120)
                    .foregroundColor(.orange)
                    .overlay(Text("(\(_x), \(self._y))"))
            }
        }
    }
}

struct Grid: View {
    var m: Int
    var n: Int

    var body: some View {
        ScrollView(.horizontal){
        ScrollView(.vertical) {
            ForEach(0 ..< n) { _y in
                Row(_y: _y, x: 0 ..< self.m)
            }
        }
        }
    }
}

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Grid").font(.title)
            Grid(m: 5, n: 5)
        }
    }
}

enter image description here

enter image description here

It is still not perfect, but usable. The best is to use only one scroll axis and fill the second direction with the right number of cells.

I miss how to know and to be able to adjust scroll position. SwiftUI is in very early stage, Once it will be more reliable, be patient

like image 166
user3441734 Avatar answered Nov 23 '25 05:11

user3441734