SwiftUI中UITableView内可变高度VStack的自适应高度优化咨询
解决UITableView中嵌入SwiftUI VStack的闪烁问题
方法一:使用PreferenceKey同步获取视图高度
你之前用onAppear获取高度会触发二次布局,因为onAppear是视图渲染完成后才执行。改用PreferenceKey可在布局过程中实时传递高度值,避免闪烁:
- 定义用于传递高度的PreferenceKey:
struct ViewHeightKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = max(value, nextValue()) } }
- 修改视图代码,通过preference传递高度并同步更新:
@State private var totalHeight: CGFloat = 0 VStack { getTopView() .background( GeometryReader { geo in Color.clear .preference(key: ViewHeightKey.self, value: geo.size.height) } ) } .padding() .onPreferenceChange(ViewHeightKey.self) { newHeight in totalHeight = newHeight } .frame(height: totalHeight)
方法二:利用UITableView自动Cell高度(推荐)
既然是在UITableView中嵌入SwiftUI视图,直接借助UIKit的自动Cell高度机制更彻底,完全无需手动计算高度:
- 封装承载SwiftUI内容的UITableViewCell:
class SwiftUIContentCell: UITableViewCell { private let hostingController = UIHostingController(rootView: AnyView(EmptyView())) override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupHostingViewConstraints() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupHostingViewConstraints() { hostingController.view.translatesAutoresizingMaskIntoConstraints = false contentView.addSubview(hostingController.view) NSLayoutConstraint.activate([ hostingController.view.topAnchor.constraint(equalTo: contentView.topAnchor), hostingController.view.leadingAnchor.constraint(equalTo: contentView.leadingAnchor), hostingController.view.trailingAnchor.constraint(equalTo: contentView.trailingAnchor), hostingController.view.bottomAnchor.constraint(equalTo: contentView.bottomAnchor) ]) } func update(with contentView: some View) { hostingController.rootView = AnyView(contentView.padding()) hostingController.view.invalidateIntrinsicContentSize() } }
- 配置UITableView开启自动高度:
// 在TableView初始化或viewDidLoad中设置 tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 150 // 设置符合你内容的预估高度
UITableView会自动根据SwiftUI视图的固有高度计算Cell高度,无二次布局操作,从根源上消除闪烁。
内容的提问来源于stack exchange,提问作者Neha Pant
相关产品推荐
相关产品推荐

