我正在尝试将一个List放入ScrollView中。
如果你想知道为什么,这是我的解释,如果不是,就跳到代码部分。我需要在我的List上面有一个平滑的缩放标题。为了做到这一点,我应该把头文件和List都放到一个ScrollView上,剩下的使用scroll content offset来完成。我还需要禁止List的内置滚动,因为它已经在ScrollView上了,并为List设置高度-这样滚动视图才能知道它的内容高度。它工作得很好,但List的高度有时是错误的。
我不能用LazyVStack代替List -它更慢(我猜没有单元重用),而且List很大。它还破坏了NavigationLinks,所以它是out -它必须是一个List。
单元格的高度不是固定的,所以我不能只手工计算。
下面是使用UITableView创建固定高度的不可滚动List的代码
struct AutosizingList<Content: View>: View {
@ViewBuilder var content: Content
@State private var tableContentHeight: CGFloat = 0
var body: some View {
List {
content
}
.introspectTableView { tableView in
tableView.isScrollEnabled = false
tableContentHeight = tableView.contentSize.height
}
.frame(height: tableContentHeight)
}
}我猜这个块并不总是在didLayoutSubviews或其他什么之后调用,这就是为什么高度有时是正确的,有时是错误的。所以我的问题是:如何可靠地获得List的身高?我可以在SwiftUI中使用远程类似于didLayoutSubviews的东西吗?
发布于 2021-09-03 05:18:03
表contentSize是根据屏幕上已经出现的单元格计算的。假设剩余单元格的大小将与前面的单元格大小相同。
您可以看到滚动指示器在滚动时是如何变化的:它可能会根据新单元格的大小而减小或增大。在我的测试中,我使用依赖于索引的单元格高度来显示此行为。
反过来,在创建视图时,introspectTableView只被调用一次:您可以检查source code。
我建议你在这种情况下使用关键路径观察:
struct ContentView: View {
@State
private var observation: NSKeyValueObservation?
var body: some View {
List {
ForEach(0..<100) { i in
Text(String(i))
.frame(height: CGFloat(i))
}
}.introspectTableView { tableView in
print("initial size", tableView.contentSize)
observation = tableView.observe(\.contentSize) { tableView, value in
print("new size", tableView.contentSize)
}
}
}
}https://stackoverflow.com/questions/69028426
复制相似问题