在使用UIHostingConfiguration的混合UIKit/SwiftUI设置中,如何在单元格内容调整大小时防止UITableView的内容跳动?
我正在尝试通过 UITableView 和 UIHostingConfiguration 来显示单元格的内容,重写我的SwiftUI滚动视图。设置本来很简单,但我在调整单元格大小方面遇到了一个阻碍。
每当单元格的内容在垂直方向增长时,表格视图就会跳动不稳,大家有什么想法来解决这个问题吗? 参考请见附上的视频:
我已将示例项目上传到GitHub:
https://github.com/wiencheck/SwiftUITableViewPOC
主要内容位于 TableViewPOC/TableViewController.swift
解决方案
看完你的代码后,我发现了以下问题:
text changes
↓
SwiftUI invalidates Text
↓
UIHostingConfiguration recalculates intrinsic height
↓
UITableView asks for new row height
↓
your controller receives objectWillChange
↓
update()
↓
dataSource.apply(snapshot)
↓
UITableView performs another layout pass
viewModel.objectWillChange
.receive(on: DispatchQueue.main)
.sink { [weak self] in
self?.update()
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
这就是造成问题的原因。
为了解决这个问题
在 ViewModel.swift:
import Combine
final class ViewModel: ObservableObject {
let sectionsChanged = PassthroughSubject<Void, Never>()
// Call this whenever sections are added/removed/reordered
func notifySectionsChanged() {
sectionsChanged.send()
}
}
在 TableViewController.swift,将以下内容替换为:
viewModel.objectWillChange
.receive(on: DispatchQueue.main)
.sink { [weak self] in
self?.update()
}
.store(in: &cancellables)
为:
viewModel.sectionsChanged
.receive(on: DispatchQueue.main)
.sink { [weak self] in
self?.update()
}
.store(in: &cancellables)
然后每当你的sections数组发生变化:
sections.append(newSection)
sectionsChanged.send()
或:
sections.removeAll { $0.id == id }
sectionsChanged.send()
同时将以下内容修改为:
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
为:
.frame(maxWidth: .infinity, alignment: .topLeading)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。