Swift中TableView选中Cell传值至下一个ViewController时数据始终为nil
问题分析与解决
核心错误点
- 数据赋值不匹配:在第一个VC的
didSelectRowAt方法中,你给第二个VC的name属性赋值了,但第二个VC的viewDidLoad里却尝试读取selectedUser?.name——你根本没给selectedUser这个属性赋值,这是显示nil的直接原因。 - 未正确展示第二个ViewController:你实例化了
PlayersDetails控制器,但没有调用present(_:animated:completion:)方法来展示它。当前代码不会打开第二个页面,你看到的第二个VC打印日志大概率是通过其他方式(比如Storyboard里的直接跳转)触发的,导致赋值逻辑还没执行就加载了第二个VC,所以打印顺序颠倒。
修正后的代码
第一个ViewController的didSelectRowAt方法修正
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { guard let selectedPlayer = feedItems[indexPath.row] as? UsersModel else { return } let storyBoard = UIStoryboard(name: "Main", bundle:nil) let nextViewController = storyBoard.instantiateViewController(withIdentifier: "PlayersDetails") as! PlayersDetails // 给第二个VC的selectedUser属性赋值,匹配后续的读取逻辑 nextViewController.selectedUser = selectedPlayer print("Print When select cell \(selectedPlayer.name ?? "nil")") // 调用present方法展示第二个页面 present(nextViewController, animated: true, completion: nil) }
第二个ViewController优化(可选)
可以给selectedUser添加属性观察者,确保赋值后自动更新UI,避免依赖viewDidLoad的执行时机:
@IBOutlet weak var lbName: UILabel! @IBOutlet weak var userImage: UIImageView! var name = "" var selectedUser : UsersModel? { didSet { lbName.text = selectedUser?.name ?? "nil" print("Print when selectedUser updated \(selectedUser?.name ?? "nil")") // 顺便处理图片加载 if let imageName = selectedUser?.userImage { let imageURL = URL(string: "https://mywebsite.com/image-upload/img/\(imageName)") userImage.sd_setImage(with: imageURL, placeholderImage: UIImage(named: "nullImageQuestion.png")) } } } override func viewDidLoad() { super.viewDidLoad() // 兜底确认UI更新 lbName.text = selectedUser?.name ?? "nil" }
额外注意事项
- 替换强制类型转换
as!为guard let/if let,避免类型不匹配时崩溃; - 确认Storyboard中
PlayersDetails控制器的Storyboard ID确实设置为PlayersDetails,否则实例化会失败。
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

