You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 13:40:33