在SwiftUI中如何让ScrollView的内容填充其父视图

28

我希望构建一个可滚动的屏幕,因此我想嵌入 ScrollView。但我无法实现它,视图只会收缩到其压缩大小。假设我希望 ScrollView 垂直滚动,因此我希望内容与 scrollView 的宽度匹配。所以我使用以下预览:

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

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

但它的结果是这样的:

在此输入图片描述


7个回答

28

使用 frame(maxWidth: .infinity) 是您的简单方法

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

13

这里有一个小技巧:引入只包含一个SpacerHStack

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

9

这是一个已知问题,也存在于beta 2版本中 - 在这里检查Apple的Xcode 11发布说明⬇️ https://developer.apple.com/documentation/xcode_release_notes/xcode_11_beta_2_release_notes.

Apple提到的解决方法是在元素内部为ScrollView设置固定框架。在这种情况下,我建议使用GeometryReader来修复屏幕宽度,高度会自动适应内容。

例如,如果您需要将ScrollView的内容调整为屏幕宽度,可以像这样进行:

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

2
发布说明的哪个部分提到了这个?我没有看到。 - Just a coder

7

实际上你不再需要使用 GeometryReader 。在 Xcode beta 3 中,ScrollView 已经进行了重构。现在你可以声明你有一个水平的 .horizontal 或垂直的 .verticalScrollView

这使得 ScrollView 的行为像它应该的那样,像任何普通的 View 协议一样。

例如:

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

这将导致视图的宽度与其父视图一样,并且可以水平滚动。高度将由ScrollView子视图的高度定义。


21
这个回答与问题完全无关。他没有询问滚动视图的方向。 - Peter Schorn
1
@PeterSchorn 这是目前填充超级视图的方式。在此之前,您必须使用geometry reader来确定正确的空间,因为我们没有.vertical或.horizontal参数,这发生在beta期间。现在,您可以像添加任何视图一样添加ScrollView。希望您明白上下文。 - Leonel Menezes Morato Lima
在 @PeterSchorn 之前,ScrollView 会调整其子视图的大小,无法显示所需的内容。 - Leonel Menezes Morato Lima
1
我认为这里出现了某种故障或误解。我的滚动视图正在占用屏幕的大小。然而,滚动视图中设置为使用所有可用空间的“自定义视图”并没有拉伸以填充滚动视图的内容。我知道它们应该这样做。如果你尝试使用典型的文本,它们确实会这样做... - Klajd Deda
@LeonelMenezesMoratoLima 这个回答仍然是错误的。 - Claus Jørgensen

4

滚动视图内容将扩展到可用大小。

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

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

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

这个解决方案修复了在我的应用程序中使用Xcode 14 beta 3中的scrollview时视图缩小(宽度)的问题...我本以为这个问题已经消失了,因为这篇文章已经超过一年了。 - Tim
这个解决方案是否有效,@Tim? - Amisha Italiya
正如我在评论中所述,是的,它正在工作... - Tim

-4

PreviewProvider 主要是关于你的 Canvas(渲染视图)。

如果你想将文本放入 ScrollView 中,你应该创建你自己的 View。

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

然后,在 Canvas 中呈现您的 MyViewWithScroll(代码编辑器右侧带有 iPhone 的窗口)

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

这只是为了简化而处于预览状态,您的答案会产生相同的结果。 - olejnjak

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