Вызов scrollTo() в onAppear() не всегда работает

См. пример кода ниже:

      struct TestView: View {
    var body: some View {
        ScrollViewReader { proxy in
                List {
                    ForEach(1...30, id: \.self) { item in
                        Text("\(item)")
                        .id(item)
                    }
                }
                .onAppear {
                    proxy.scrollTo(8, anchor: .topLeading)
                }
        }
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            NavigationLink("test") {
                TestView()
            }
        }
    }
}

Два наблюдения:

  1. Если я не поставлю TestViewв NavigationLink(например, поместите его прямо в ContentView), код работает нормально.

  2. Следующий diff решает эту проблему:

                              .onAppear {
     -                    proxy.scrollTo(8, anchor: .topLeading)
     +                    DispatchQueue.main.async() {
     +                        proxy.scrollTo(8, anchor: .topLeading)
     +                    }
                      }
    

Кто-нибудь знает, в чем первопричина? Обходной путь предполагает, что это проблема синхронизации, что объясняет мое наблюдение 1, где нет анимации навигации. Итак, это потому, что при запуске анимация все еще продолжается и, следовательно, proxy.scrollTo()молча выходит из строя? Но если так, то не должна ли Apple предоставить версию onAppear()который запускается после завершения анимации? Текущий обходной путь выглядит слишком хакерским. Я нашел его в сети, и есть разные версии, некоторые используют async(), некоторые используют asyncAfter(), что говорит о том, что ни один из них не является надежным.

0 ответов

Другие вопросы по тегам