在iOS 16中,列表中的嵌套ScrollView和可刷新操作可能会出现奇怪的行为。

8
在我的SwiftUI应用程序中,我有一个带有嵌套ScrollView的列表,在我的iPhone升级到iOS 16后,主列表的刷新有奇怪的行为。似乎每个ScrollView都有自己的刷新。问题在于我已经在主列表上应用了.refreshable修改器,而不是在嵌套列表上应用。在iOS 16之前不存在这个问题。那么,这是一个错误还是我们可以以某种方式修复它?以下是代码和短视频:
List {
    VStack(alignment: .leading) {
        Text("Line 1")
            .font(.title)
        
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack(spacing: 20) {
                Text("Item 1")
                Text("Item 2")
                Text("Item 3")
                Text("Item 4")
                Text("Item 5")
                Text("Item 6")
                Text("Item 7")
                Text("Item 8")
                Text("Item 9")
                Text("Item 10")
            }
            .frame(height: 180)
        }
    }
    .listRowSeparator(.hidden)
    
    VStack(alignment: .leading) {
        Text("Line 2")
            .font(.title)
        
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack(spacing: 20) {
                Text("Item 1")
                Text("Item 2")
                Text("Item 3")
                Text("Item 4")
                Text("Item 5")
                Text("Item 6")
                Text("Item 7")
                Text("Item 8")
                Text("Item 9")
                Text("Item 10")
            }
            .frame(height: 180)
        }
    }
    .listRowSeparator(.hidden)
}
.listStyle(.plain)
.refreshable {
    print("refresh!")
}

Video of the issue


新的iOS版本中似乎已经修复了这个问题! - mattialerda
4个回答

4

如果你将你的List更换为一个ScrollView,然后将.listStyle(.plain)这一行更改为.padding(.horizontal),那么它将在不出现错误的情况下正常工作。


1
谢谢!我没想过尝试这个。唯一的问题是,在旧版本的iOS上,ScrollView不支持.refreshable。我加了一个if #available (iOS 16, *),这是最好的处理方式吗? - mattialerda
.refreshable 在 iOS 15 的 ScrollView 上也可用。我猜你使用的是这个版本,因为 refreshable(action:) 只在 iOS 15.0 或更新版本中可用。 - Roland Lariotte
1
我在我的iPad(iOS 15.7)上尝试过,但它不起作用。我读到.refreshable在iOS 15上适用于List,而不适用于ScrollView。苹果公司在iOS 16中为ScrollView添加了.refreshable - mattialerda
你用的是哪款iPad?我在Xcode 14.0.1 (14A400)上使用ScrollViewrefreshable(action:)构建并运行代码,同时在iOS 15上运行iPad Pro 11英寸和iPhone 14 Pro模拟器。 - Roland Lariotte

1

如果您不想从列表(List)切换到滚动视图(ScrollView)(因为ScrollView不会重用单元格),可以使用.introspectScrollView。对于列表中的scrollView,将isDirectionalLockEnabled设置为true,并将bounces设置为false以避免此问题。

.introspectScrollView { scrollView in
     scrollView.isDirectionalLockEnabled = true
     scrollView.bounces = false
}

1

我假设这就是你要找的答案:

https://dev59.com/B3QOtIcB2Jgan1znhUwC#75834493

所以在你的嵌套列表或滚动视图中,你需要添加这个修饰符:

List/ScrollView {

}.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)

0

在您的嵌套滚动视图上尝试一下这个 ;)

.environment(\EnvironmentValues.refresh as! WritableKeyPath<EnvironmentValues, RefreshAction?>, nil)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接