【问题标题】:Make ScrollView content fill its parent in SwiftUI让 ScrollView 内容在 SwiftUI 中填充其父级
【发布时间】:2019-10-22 08:22:23
【问题描述】:

我很想构建一个滚动屏幕,所以我想嵌入它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()
            }
        }
    }
}

但结果是这样的:

【问题讨论】:

标签: swift swiftui


【解决方案1】:

一个简单的方法,使用 frame(maxWidth: .infinity)

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

【讨论】:

    【解决方案2】:

    实际上,您不再需要几何阅读器了。 ScrollView 在 XCode beta 3 中进行了重构 现在你可以声明你有一个 .horizo​​ntal ScrollView 或一个 .vertical 这使得 ScrollView 表现得像任何普通的 View 协议一样。

    例如:

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

    这将导致其父级宽度水平滚动的视图。 高度将由 ScrollView 的子视图高度定义。

    【讨论】:

    • 这个答案与问题完全无关。他没有问滚动视图的方向。
    • @PeterSchorn 这是目前填充超级视图的方式。在此之前,您必须使用几何阅读器来了解正确的空间,因为我们没有 .vertical 或 .horizo​​ntal 参数,这是在 beta 期间发生的。现在您可以像添加任何视图一样添加 ScrollView。我希望你理解上下文。
    • @PeterSchorn 在它之前,ScrollView 会调整其子视图的大小,而不是显示所需的内容。
    • 我认为这里的某处存在故障或误解。我的滚动视图正在占用屏幕的大小。但是,滚动内的“自定义视图,设置为使用所有可用空间”不会拉伸以填充滚动视图的内容。我知道他们应该。例如,如果您使用典型的 Text 他们会这样做...
    • @LeonelMenezesMoratoLima 这个答案仍然是错误的。
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      这是一个在 beta 2 中也存在的已知问题 - 在此处查看 Apple 的 Xcode 11 发行说明⬇️ https://developer.apple.com/documentation/xcode_release_notes/xcode_11_beta_2_release_notes.

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

      例如,如果您需要使 ScrollView 的内容适应屏幕宽度,您可以这样做:

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

      【讨论】:

      • 他们在发行说明的哪个部分提到了这一点?我没看到。
      【解决方案5】:
      • 您也可以使用额外的 HStack 和空间来完成此操作。

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

      【讨论】:

        【解决方案6】:

        PreviewProvider 只是关于您的 Canvas(渲染视图)。

        如果你想将文本放入 ScrollView,你应该创建你的视图

        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
        

        【讨论】:

        • 预览版只是为了简化,您的回答会产生相同的结果。