ScrollViewReader 滚动在 iOS 15 上滚动太多

问题描述 投票:0回答:1

在iOS 15上,ScrollViewReader的scrollTo存在问题,滚动太多。 我有一个按钮和一个日期选择器,点击按钮时我会显示日期选择器,但我想确保日期选择器在屏幕上完全可见,所以我滚动到它。重现问题的代码附在下面:

import SwiftUI

struct ScrollToIssue: View {
    @State var showPicker: Bool = false
    @State var date: Date = Date()
    
    var body: some View {
        ScrollViewReader { scrollViewReader in
            ScrollView {
                
                Color.red.frame(height: 400)
                
                Color.yellow.frame(height: 200)
                
                VStack {
                    Button(action: {
                        showPicker.toggle()
                        
                        if showPicker {
                            DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                                withAnimation {
                                    scrollViewReader.scrollTo("pickerrrr")
                                }
                            })
                        }
                    }, label: {
                        Text("Show picker")
                    })
                    
                    if showPicker {
                        DatePicker(selection: $date,
                                   displayedComponents: .date,
                                   label: { EmptyView() })
                        .labelsHidden()
                        .datePickerStyle(GraphicalDatePickerStyle())
                        .id("pickerrrr")
                    }
                }
                .border(Color.green)
                
                Color.blue.frame(height: 500)
            }
        }
    }
}

在 iOS 16/17 上运行良好。还尝试将 ScrollViewReader 移动到 ScrollView 的内部/外部,没有区别,也尝试使用锚点 .bottom,仍然是同样的问题。

我将 Xcode 15.0 与 Iphone 13、iOS 15.5 一起使用

ios swiftui scrollview scrollto scrollviewreader
1个回答
0
投票

我相信这是 SwiftUI 中的一个错误。

还有很多人已经遇到过同样的问题。 https://developer.apple.com/forums/thread/688230

无论如何,您可以通过使用

LazyVStack
而不是
VStack
来避免此问题。

注意:我还没有更新我的 macOS,所以我使用的是 Xcode 14.3,所以我还没有针对 iOS 17 进行测试。

struct ScrollToIssue: View {
  @State var showPicker: Bool = false
  @State var date: Date = Date()
  
  var body: some View {
    ScrollViewReader { scrollViewReader in
      ScrollView {
        
        Color.red.frame(height: 400)
        
        Color.yellow.frame(height: 200)
        
        LazyVStack {  // 👀 Instead of VStack
          Button(action: {
            showPicker.toggle()
            
            if showPicker {
              DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
                withAnimation {
                  scrollViewReader.scrollTo("pickerrrr")
                }
              })
            }
          }, label: {
            Text("Show picker")
          })
          
          if showPicker {
            DatePicker(selection: $date,
                       displayedComponents: .date,
                       label: { EmptyView() })
            .labelsHidden()
            .datePickerStyle(GraphicalDatePickerStyle())
            .id("pickerrrr")
          }
        }
        .border(Color.green)
        
        Color.blue.frame(height: 500)
      }
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.