请看tvOS(版本14.7 18 M60)上滚动这个简单示例:
struct TestView: View
{
var body: some View {
ScrollView (.vertical, showsIndicators: false, content: {
ForEach(0..<600) { index in
Button(action: {}, label: {Text("Button - \(index)")})
.background(Color.blue)
.padding()
}
})
}
}
这个例子在连续滚动时会表现得很糟糕,滚动会停止移动,等待我在遥控器上完成滚动,在我在Apple TV遥控器上完成滑动后只有半秒钟,它就会更新视图并滚动到请求的位置,
See a video with this behavior
显然,这是一个不希望的行为,因为在滑动过程中,我看不到我已经到达了哪里,因此我必须停止滑动,允许视图刷新,只有在我看到滚动已经到达了哪里之后,我才可以决定是继续滚动还是向上滚动(如果需要)
它看起来像一个SwiftUI(尝试)优化性能,但它破坏了整个亚视应用程序的体验
我尝试使用ScrollViewReader修复它,如下所示:
import Foundation
import SwiftUI
struct FocusableButton: View
{
@State var isFocused = false
let index: Int
var scrollView: ScrollViewProxy
var body: some View
{
VStack
{
Text("Button - \(index)")
}
.id(index)
.frame(width: 200, height: 100)
.padding()
.scaleEffect(isFocused ? 1.1 : 1)
.background(isFocused ? Color.white : Color.blue)
.focusable(true, onFocusChange: { focused in
isFocused = focused
(focused ? {
scrollView.scrollTo(index)
}() : { /* Lost Focus */ }())
})
}
}
struct TestView: View
{
var body: some View {
ScrollViewReader { scrollView in
ScrollView (.vertical, showsIndicators: false, content: {
ForEach(0..<600) { index in
FocusableButton(index: index, scrollView: scrollView)
}
})
}
}
}
see a video of how it behaves after the fix
但如果滚动太快-自动分页滚动启动并使应用程序崩溃,我会得到错误(在Xcode中):
Fatal error: ScrollViewProxy may not be accessed during view updates
和运行时问题:
Modifying state during view update, this will cause undefined behavior.
有没有人能帮忙?有没有办法解决它?(滚动问题或错误)
即使有一种方法可以绕过自动分页滚动,我也希望看到一个代码示例
1条答案
按热度按时间shstlldc1#
奇怪的事实:如果你用一个
List
包围ScrollView
(即使是1个虚拟项)-滚动行为正确,所以我用
List
实现了这个测试,它表现正确:所以我目前的结论是:
行不通!
如果我删除
focusable
并将其替换为button
,则ScrollView
和ForEach
也可以正常工作:但这三个组合(ScrollView + ForEach + focusable)的表现很差