UITableViewCell动态数据传递至SwiftUI View时出现nil问题求助
解决UITableViewCell数据传递到SwiftUI View后变为nil的问题
问题根源
- 你把
HandMeasurementsTableViewCell当作ObservableObject使用,但TableView的Cell是视图复用对象,本身不该承担ViewModel的职责;而且你在SwiftUI View里直接新建了一个HandMeasurementsTableViewCell实例,这和TableView中正在使用的Cell是完全不同的对象,自然拿不到已赋值的数据。 - 数据传递路径错误:应该统一管理数据源,而非通过Cell作为中转载体。
修复步骤
1. 新建独立的ViewModel类
把数据逻辑从Cell中抽离,创建专门的ViewModel管理手指测量数据:
class FingerSizeViewModel: ObservableObject { @Published var fingerSizeData: SaveNailImagesResponse? }
2. 修改UITableViewCell,移除ObservableObject继承
Cell只负责展示数据,不需要继承ObservableObject:
class HandMeasurementsTableViewCell: UITableViewCell { // 直接接收数据并更新UI var fingerSizeData: SaveNailImagesResponse? { didSet { // 在这里更新Cell上的UI控件(比如对应label) print(fingerSizeData?.leftIndexSize as Any) print(fingerSizeData?.leftRingSize as Any) print(fingerSizeData?.leftMiddleSize as Any) } } }
3. 在ViewController中持有ViewModel实例
统一管理数据源,将ViewModel传递给Cell和SwiftUI View:
class ResultsSizesViewController: UIViewController { @IBOutlet weak var tableView: UITableView! // 持有ViewModel实例,统一管理数据 let fingerSizeVM = FingerSizeViewModel() override func viewDidLoad() { super.viewDidLoad() // ... 原有代码不变 // 将获取到的resultsData赋值给ViewModel fingerSizeVM.fingerSizeData = self.resultsData } @objc func presentThumbnailPage() { // 将ViewModel传入SwiftUI View let rootView = ResultsThumbnailView1(data: fingerSizeVM) let vc = UIHostingController(rootView: rootView) vc.modalPresentationStyle = .fullScreen self.navigationController?.present(vc, animated: true) } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "HandMeasurementsTableViewCell") as? HandMeasurementsTableViewCell // 从ViewModel获取数据传给Cell cell?.fingerSizeData = fingerSizeVM.fingerSizeData if indexPath.row == 0 { cell?.titleLabel.text = "Left Hand" } else if indexPath.row == 1 { cell?.titleLabel.text = "Right Hand" } return cell! } // ... 其他代码不变 }
4. 修改SwiftUI View,接收ViewModel
不再依赖Cell,直接接收ViewModel实例:
struct ResultsThumbnailView1: View { @Environment(\.presentationMode) var presentationMode // 使用ObservedObject监听ViewModel的变化 @ObservedObject var data: FingerSizeViewModel var body: some View { VStack { Text(String(data.fingerSizeData?.leftRingSize ?? 0)) Text("Size \(String(data.fingerSizeData?.leftIndexSize ?? 0))") .font(.system(size: 19, weight: .bold)) } } }
额外说明
- 永远不要把UI组件(比如UITableViewCell、UIView)当作
ObservableObject使用,ViewModel应该是独立于视图的逻辑载体,负责管理数据和业务逻辑。 - 数据要统一在ViewModel中管理,所有需要使用数据的视图(Cell、SwiftUI View)都从ViewModel获取,避免数据分散导致的传递错误。
内容的提问来源于stack exchange,提问作者LeetCodeBum
相关产品推荐
相关产品推荐

