【问题标题】:SwiftUI, How to scroll to the top?SwiftUI,如何滚动到顶部?
【发布时间】:2020-03-23 15:19:49
【问题描述】:

我正在使用 ScrollView,当我执行任何操作(例如单击按钮等)时,是否可以将视图滚动到顶部?

【问题讨论】:

标签: swift swiftui


【解决方案1】:

在刚刚发布的ScrollViewProxy

允许以编程方式滚动视图层次结构中的可滚动视图的代理值。 – https://developer.apple.com/documentation/swiftui/scrollviewproxy

Xcode 12.0 beta (12A6159)

【讨论】:

    【解决方案2】:

    我认为目前最好的方法是使用 View 的 id 函数

    1. 声明一个具有唯一 ID 的状态变量
        @State private var scrollViewID = UUID()
    
    1. 然后将id函数添加到ScrollView

      ScrollView(.horizontal, showsIndicators: true) {
      // ...
      }.id(self.scrollViewID)
      
      

    每当您更改该 ID - 例如在按钮事件中 - 滚动视图都会从头开始重建 - 这就像滚动到顶部

    【讨论】:

    • 当我尝试这个时,我看到视图重新评估但滚动位置保持不变。
    【解决方案3】:

    有一种解决方法可以通过在显示新内容之前隐藏所有内容来实现 ScrollToTop() 效果。

    @State var hideEverything = false
    
    var body: some View {
      ScrollView {
        if hideEverything {
          EmptyView()
        } else {
          // your content view
        }
      }
    }
    
    func ScrollToTop() {
      self.hideEverything = true
      DispatchQueue.main.asyncAfter(deadline: .now() + 0.01)  
      {  
        self.data = ... // update data source
        self.hideEverything = false
      }
    }
    

    【讨论】:

      【解决方案4】:

      使用this 解决方案(以前简化)我做了一个例子,当按下按钮时将ScrollView.content.offsetstrict 移到顶部:

      struct ScrollToTheTop: View {
      
          @State private var verticalOffset: CGFloat = 0.0
          @State private var gestureOffset: CGFloat = 0.0
          @State private var itemCount: Int = 200
      
          var body: some View {
      
              NavigationView {
                  VStack {
      
                      ScrollView(.vertical, showsIndicators: false) {
      
                          VStack {
      
                              ForEach(1...itemCount, id: \.self) { item in
                                  Text("--- \(item) ---") // height 17.5
                              }
      
                          }
      
                      }
                      .content.offset(y: (self.verticalOffset + self.gestureOffset)
                          // all the content divided by 2 for zero position of scroll view
                          + CGFloat(17.5 * Double(self.itemCount/2)))
                          .gesture(DragGesture().onChanged( { value in
                              self.gestureOffset = value.translation.height
                          }).onEnded( { value in
                              withAnimation {
                                  // here should calculate end position with value.predictedEndLocation.y
                                  self.verticalOffset += value.translation.height
                                  self.gestureOffset = 0.0
                              }
                          }))
      
      
                  }.navigationBarItems(trailing: Button("To top!") {
                      withAnimation {
                          self.verticalOffset = 0.0
                      }
                  })
              }
      
          }
      
      }
      

      如果这个例子适合,你必须细化DragGesture

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-07
        • 1970-01-01
        • 2022-11-27
        • 2021-07-14
        • 2021-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多