模态视图控制器中Unwind Segue触发过早问题求助
解决Unwind Segue执行早于数据赋值的问题
这个问题我做iOS项目时也碰到过,核心原因很明确:你把unwind segue直接绑定在了tableViewCell上,系统的执行顺序是先触发segue的跳转逻辑,再调用didSelectRowAt方法,所以你在didSelectRowAt里给favoriteArtist赋的新值,根本赶不上父控制器读取它,自然就只能拿到默认值了。
给你两个靠谱的解决思路,任选其一都能解决问题:
方法1:手动触发Unwind Segue(简单直接)
- 先打开Storyboard,删掉原来绑定在cell上的unwind segue(选中segue按Delete键即可)
- 给你的unwind segue设置一个标识符:选中父控制器和子控制器之间的unwind segue,在右侧Attributes Inspector里填写Identifier,比如
UnwindToArtistVC - 修改
ViewControllerArtistSearch里的didSelectRowAt方法,先完成数据赋值,再手动触发segue:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // 先赋值选中的艺术家名称 favoriteArtist = names[indexPath.row] print(favoriteArtist) // 手动触发unwind segue,替换成你自己设置的标识符 performSegue(withIdentifier: "UnwindToArtistVC", sender: self) }
这样一来,数据赋值会先完成,再执行segue跳转,父控制器就能拿到正确的新值了。
方法2:使用prepare(for:sender:)传递数据(更符合iOS规范)
这是苹果推荐的segue数据传递方式,不管segue是自动触发还是手动触发,prepare(for:sender:)都会在segue执行过程中被调用,而且是在跳转之前,完全不用担心执行顺序问题。
修改ViewControllerArtistSearch,添加prepare(for:sender:)方法:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { // 先确认是我们要处理的unwind segue guard segue.identifier == "UnwindToArtistVC", let parentVC = segue.destination as? 你的父控制器类名 else { return } // 获取当前选中的行对应的艺术家名称 if let indexPath = tableView.indexPathForSelectedRow { let selectedArtist = names[indexPath.row] // 可以直接给父控制器的label赋值,或者给当前控制器的favoriteArtist赋值 favoriteArtist = selectedArtist // 或者更直接:parentVC.artist1.text = selectedArtist } }
另外,建议你把父控制器里的unwind方法改得更安全一点,去掉强制解包,避免崩溃:
@IBAction func unwindFromArtist(segue: UIStoryboardSegue) { if let source = segue.source as? ViewControllerArtistSearch { artist1.text = source.favoriteArtist } }
用这种方法的话,甚至可以不用didSelectRowAt里的赋值逻辑,直接在prepare里处理数据传递就行,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Levi Weiss
相关产品推荐
相关产品推荐

