子类中@Published属性包装器失效问题求助
SwiftUI中继承父类的ObservableObject子类在视图重建后@Published失效问题
我有一个继承自DashboardTradableViewModel的子类DashboardWatchlistViewModel,该子类实现了ObservableObject协议,内部包含@Published修饰的isHighlighted和chartViewModel字段。这个模型对应的DashboardWatchlistView用于单元格中,首次创建视图时@Published能正常触发视图更新,但当单元格因数据更新频繁重建视图并传入新模型实例后,@Published就不再生效(比如高亮功能失效)。移除继承关系后,所有功能恢复正常。
我曾找到过类似的SwiftUI Bug相关问题,尝试调用self.objectWillChange.send()方法也没能解决问题。
相关代码
模型代码
final class DashboardWatchlistViewModel: DashboardTradableViewModel, ObservableObject { @Published var isHighlighted = false @Published var chartViewModel: AssetLineChartViewRepresentable.ViewModel? ........ init(.....) { super.init() } }
父模型代码
class DashboardTradableViewModel { // MARK: - Properties // MARK: - Init init(....) { } }
视图创建代码(频繁调用)
func configure(with viewModel: DashboardWatchlistViewModel) { print("Tag1 configure") self.dashboardWatchlistView = DashboardWatchlistView(viewModel: viewModel) self.viewModel = viewModel viewModel.chartDataEvent.compactMap { $0 } .receive(on: DispatchQueue.main) .sink { [weak self] chartData in viewModel.chartViewModel = AssetLineChartViewRepresentable.ViewModel(chartData: chartData, percentageChange: viewModel.percentageChange2) } .store(in: &cancellables) }
视图代码
struct DashboardWatchlistView: View { private struct Layout { static let imageHeight: CGFloat = 40 static let imageWidth: CGFloat = 40 static let topPadding: CGFloat = 10 static let frameHeight: CGFloat = 69 static let cornerRadius: CGFloat = 9 static let scaleFactor: CGFloat = 1.0 } @ObservedObject var viewModel: DashboardWatchlistViewModel var body: some View { VStack(alignment: .center) { ZStack { HStack(spacing: .designSystem(.extraSmall4)) { HStack(spacing: .designSystem(.small)) { KFImage(viewModel.logoURL) .serialize(by: SVGCacheSerializer()) .setProcessor(SVGProcessor()) .scaleFactor(Layout.scaleFactor) .resizable() .placeholder { Circle() .fill(Color(viewModel.placeholderColor.isEmpty ? .gray : UIColor(hex: viewModel.placeholderColor))) } .frame(width: Layout.imageWidth, height: Layout.imageHeight) .clipShape(RoundedRectangle(cornerRadius: Layout.imageWidth / 2)) .overlay(RoundedRectangle(cornerRadius: Layout.imageWidth / 2).stroke(.white, lineWidth: 2 / UIScreen.main.scale)) VStack(alignment: .leading, spacing: .designSystem(.extraSmall3)) { HStack { Text(viewModel.leftTitle).font(.subheadline).fontWeight(.semibold).lineLimit(1) } Text(viewModel.leftSubtitle).font(.caption2).foregroundColor(Color(ThemeManager.current.neutral50)) } } Spacer() if let chartViewModel = viewModel.chartViewModel { AssetLineChartViewRepresentable(viewModel: chartViewModel).frame(width: 65, height: 20) } VStack(alignment: .trailing, spacing: .designSystem(.extraSmall3)) { percentChangeView(assetPercentChangeType: viewModel.assetPercentChangeType) Text(viewModel.rightSubtitle).font(.caption2).foregroundColor(Color(ThemeManager.current.neutral50)) } .padding(.leading, .designSystem(.medium)) } .padding([.leading, .trailing]) if !viewModel.hideSeparator { VStack { Spacer() Divider().padding(.leading) } } } } .frame(height: Layout.frameHeight) .background( backgroundView(assetPositionType: viewModel.corners) ) } }
问题演示

内容的提问来源于stack exchange,提问作者Artiom
相关产品推荐
相关产品推荐

