在 SwiftUI 中使 ScrollView 内容填充其父级
Make ScrollView content fill its parent in SwiftUI
我很想构建一个滚动屏幕,所以我想嵌入它 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()
}
}
}
}
但它以这样的结果结束:
PreviewProvider 与您的Canvas(渲染视图)有关。
如果您想将文本放入 ScrollView 中,您应该创建自己的视图
struct MyViewWithScroll : View {
var body: some View {
ScrollView {
Text("Placeholder")
}
}
}
然后,在 Canvas 中呈现您的 MyViewWithScroll(window 和代码编辑器右侧的 iPhone)
#if DEBUG
struct MyViewWithScroll_Previews : PreviewProvider {
static var previews: some View {
MyViewWithScroll()
}
}
#endif
这里有一个技巧:引入一个只有一个 Spacer
的 HStack
:
return Group {
HStack {
Spacer()
}
textfield()
ScrollView {
textfield()
}
}
这是 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)
}
}
}
实际上您不再需要 Geometry reader。
ScrollView 已在 XCode beta 3 中重构
现在你可以声明你有一个.horizontal ScrollView,或者一个.vertical
这使得 ScrollView 的行为就像任何普通的 View 协议一样。
例如:
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach((1...10).reversed()) {
AnyViewYouWant(number: [=10=])
}
}
}
这将导致视图水平滚动时具有其父级的宽度。
高度将由 ScrollView 的子视图高度定义。
一个简单的方法,使用 frame(maxWidth: .infinity)
ScrollView(.vertical) {
VStack {
ForEach(0..<100) {
Text("Item \([=10=])")
}
}
.frame(maxWidth: .infinity)
}
您也可以使用额外的 HStack 和 space。
ScrollView(.vertical) {
HStack {
VStack {
ForEach(0..<100) {
Text("Item \([=10=])")
}
}
Spacer()
}
}
我很想构建一个滚动屏幕,所以我想嵌入它 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()
}
}
}
}
但它以这样的结果结束:
PreviewProvider 与您的Canvas(渲染视图)有关。
如果您想将文本放入 ScrollView 中,您应该创建自己的视图
struct MyViewWithScroll : View {
var body: some View {
ScrollView {
Text("Placeholder")
}
}
}
然后,在 Canvas 中呈现您的 MyViewWithScroll(window 和代码编辑器右侧的 iPhone)
#if DEBUG
struct MyViewWithScroll_Previews : PreviewProvider {
static var previews: some View {
MyViewWithScroll()
}
}
#endif
这里有一个技巧:引入一个只有一个 Spacer
的 HStack
:
return Group {
HStack {
Spacer()
}
textfield()
ScrollView {
textfield()
}
}
这是 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)
}
}
}
实际上您不再需要 Geometry reader。 ScrollView 已在 XCode beta 3 中重构 现在你可以声明你有一个.horizontal ScrollView,或者一个.vertical 这使得 ScrollView 的行为就像任何普通的 View 协议一样。
例如:
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach((1...10).reversed()) {
AnyViewYouWant(number: [=10=])
}
}
}
这将导致视图水平滚动时具有其父级的宽度。 高度将由 ScrollView 的子视图高度定义。
一个简单的方法,使用 frame(maxWidth: .infinity)
ScrollView(.vertical) {
VStack {
ForEach(0..<100) {
Text("Item \([=10=])")
}
}
.frame(maxWidth: .infinity)
}
您也可以使用额外的 HStack 和 space。
ScrollView(.vertical) { HStack { VStack { ForEach(0..<100) { Text("Item \([=10=])") } } Spacer() } }