如何在SwiftUI中设置ScrollView的contentInset

33
我似乎找不到如何设置ScrollView的contentInset。我的目标是使ScrollView中的最后一个对象位于紫色主按钮的上方。

enter image description here

如果有一个命令,有人可以帮忙将其实现到我下面的现有代码中吗?我会非常感激你的帮助!
struct Overview: View {
    var body: some View {
        
        NavigationView {
            
            ScrollView(showsIndicators: false) {
                VStack(spacing: 10) {
                    ForEach(0..<5) {
                        Text("Item \($0)")
                            .foregroundColor(.white)
                            .font(.largeTitle)
                            .frame(width: 340, height: 200)
                            .background(Color("Boxes"))
                            .cornerRadius(10)
                    }
                }
                .frame(maxWidth: .infinity)
            }
            .navigationBarHidden(false)
            .navigationBarTitle("Overview", displayMode: .automatic)
        }
    }
}
6个回答

46

只需为ScrollView内嵌的VStack添加padding即可。

在嵌套栈中使用填充提供了与内容插图相同的行为。

ScrollView(showsIndicators: false) {
    VStack(spacing: 10) {
        // Some content //
    }
    .padding(.bottom, 200)    // Choose a value that works for you
}

11
我认为这应该成为被接受的答案。 - Piidro
1
这种方法的问题在于,如果您使用模糊和视觉效果视图,内容将无法在底部滚动。因此,当您向下滚动到文本输入区域以下时,您将失去在消息应用程序中看到的那种不错的效果。真的不知道如何实现并保持滚动指示器。 - alionthego
如果您使用ZStackvisualEffectView放在ScrollView的顶部,那么这种方法应该不会有问题。 - Jorge Frias
Jorge Fries,滚动指示器确实存在问题。 - pommefrite

23

你可以在ScrollView内容下方放置一个不可见的视图,并给它底部填充。

例如,使用Color.clear并设置300的底部填充。

struct Overview: View {
    var body: some View {
        
        NavigationView {
            
            ScrollView(showsIndicators: false) {
                VStack(spacing: 10) {
                    ForEach(0..<5) {
                        Text("Item \($0)")
                            .foregroundColor(.white)
                            .font(.largeTitle)
                            .frame(width: 340, height: 200)
                            .background(Color("Boxes"))
                            .cornerRadius(10)
                    }

                    Color.clear.padding(.bottom, 300)
                }
                .frame(maxWidth: .infinity)
            }
            .navigationBarHidden(false)
            .navigationBarTitle("Overview", displayMode: .automatic)
        }
    }
}

12
在我看来,“Spacer(minLength: 300)”比一个空的颜色更好。 - Jon Willis
13
虽然这个方法可行,但是滚动条不会像插入文本时那样自动调整。 - Doug
8
这是一个黑客行为,不算真正的解决方案。 - Sherwin Zadeh

22

iOS 15的SwiftUI现在有一个safeAreaInset修饰符。
它还可以正确调整滚动条。

ScrollView(.vertical, showsIndicators: true) {
    // scrollview's content
}
.safeAreaInset(edge: .bottom, spacing: 0) {
    // some bottom-sticked content, or just –
    Spacer()
        .frame(height: 44)
}

与上述问题相同,这个解决方案存在一个问题:滚动指示器没有正确地跟随 :/ - Nicolai Harbo
我认为这种方式指示器的位置是正确的。ScrollView可以自动调整其指示器。 - Rufus
这对我有效,它也调整了滚动指示器。在 iOS 16.4 上进行测试。 - OscarVGG

0
在iOS 15中,我只需向VStack添加负填充即可。
struct Overview: View {
    var body: some View {
        
        NavigationView {
            
            ScrollView(showsIndicators: false) {
                VStack(spacing: 10) {
                    ForEach(0..<5) {
                        Text("Item \($0)")
                            .foregroundColor(.white)
                            .font(.largeTitle)
                            .frame(width: 340, height: 200)
                            .background(Color("Boxes"))
                            .cornerRadius(10)
                    }
                    .padding(.top, -50)
                }
                .frame(maxWidth: .infinity)
            }
            .navigationBarHidden(false)
            .navigationBarTitle("Overview", displayMode: .automatic)
        }
    }
}

这是错误的,负填充不能达到与内容插入相同的效果。 - Tadreik

0

这篇文章提供了一个相当不错的解决方案,似乎可以在iOS13+上正常工作,并自动计算正确的插入值,因此您无需猜测。但它似乎并没有处理滚动指示器。


0

你只需要添加一些堆栈

struct Overview: View {
    var body: some View {
        
        NavigationView {
            
            ScrollView(showsIndicators: false) {
                VStack(spacing: 10) {
                    VStack {}.frame(width: 16, height: 40)
                    ForEach(0..<5) {
                        Text("Item \($0)")
                    }
                    VStack {}.frame(width: 16, height: 40)
                }
            }
            .navigationBarHidden(false)
            .navigationBarTitle("Overview", displayMode: .automatic)
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接