最近,我通过开发一个小应用程序开始研究ios / swiftui,该应用程序有一个卡片列表,用于显示从服务器加载的图片和消息。
我当时使用 List 来保存这些卡片,但是默认的列表“装饰”(分隔线,箭头,敲击效果)与我的卡片视图一起看起来不太好。我通过在 SceneDelegate 中添加以下代码来禁用它们:
UITableView.appearance().separatorColor = .clear
UITableViewCell.appearance().selectionStyle = .none
并且有某种技巧可以隐藏箭头:
List {
ForEach(0..<self.store.data.count, id: \.self) { idx in
NavigationLink(destination: DetailView(item: self.store.data[idx])) {
EmptyView()
}.frame(width: 0).opacity(0)
ItemCard(item: self.store.data[idx])
}
BottomLoader().onAppear {
if self.store.status != .loading {
self.store.load()
}
}
}
但是,问题在于,在SceneDelegate中隐藏列表的选择样式和分隔符颜色适用于App中的所有列表,而我确实有几个列表(例如设置中的一个)需要这些样式。
然后,我尝试将持卡人从 List 更改为 ScrollView ,但这又带来了另一个麻烦,即上一个视图的 onAppear 回调( BottomLoader)与ScrollView onAppear 同时被调用。
据我了解, onAppear 应该在呈现和显示视图时调用。 List作为项目持有者,不必计算所有项目的全高,这可能就是List仅呈现要进入屏幕的项目的原因。但是 ScrollView 确实需要知道所有项目的全高,这就是为什么所有项目都被渲染的原因。
下面是两个小段,用于显示List和ScrollView的不同行为:
List {
ForEach(0..<100) { idx in
Text("item # \(idx)").padding().onAppear { print("\(idx) on appear") }
}
}
// only 18 logs printed
并且:
ScrollView {
ForEach(0..<100) { idx in
Text("item # \(idx)").padding().onAppear { print("\(idx) on appear") }
}
}
// all 100 logs printed
有什么方法可以让ScrollView像List一样在它们要进入屏幕时呈现其子视图。 或者,有什么方法可以将这些默认样式禁用到特定的列表中,而不是全局禁用?