在开发iOS应用时,页面之间的跳转和数据传递是最常见的需求之一。比如从商品列表点进详情页,就得把商品ID带过去;或者登录成功后,要把用户信息传给个人中心。这些场景都离不开页面跳转传参。
UIStoryboardSegue 传参
使用Storyboard时,最常见的就是通过UIStoryboardSegue来传参。在触发跳转前,系统会调用prepare(for:sender:)方法,我们可以在这里把数据塞给目标页面。
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
let destinationViewController = segue.destination as! DetailViewController
destinationViewController.itemID = selectedItemId
destinationViewController.userInfo = currentUser
}
}
这种方式适合Storyboard和XIB项目,逻辑集中,不容易出错。
手动跳转传参
如果不用Storyboard,纯代码创建界面,那就得手动push或present。传参就更直接了,在跳转前给目标控制器赋值就行。
let detailVC = DetailViewController()
detailVC.itemName = "iPhone 15"
detailVC.price = 5999
navigationController?.pushViewController(detailVC, animated: true)
这种写法灵活,适合组件化项目或者混合架构的应用。
闭包传值(反向传参)
有时候不是往前传,而是往回传。比如从设置页改完昵称,返回个人中心要更新显示。这时候可以用闭包。
let settingVC = SettingViewController()
settingVC.onNameUpdated = { newName in
self.userNameLabel.text = newName
}
present(settingVC, animated: true)
在SettingViewController里调用onNameUpdated?("新名字")就能把数据传回来。这种方式轻量,不需要代理那么繁琐。
通知中心传参
当页面层级深,或者多个页面需要响应同一事件时,可以用NotificationCenter。比如退出登录,多个页面都要清空数据。
// 发送通知
NotificationCenter.default.post(name: NSNotification.Name("UserLoggedOut"), object: nil)
// 接收通知
NotificationCenter.default.addObserver(self, selector: #selector(handleLogout), name: NSNotification.Name("UserLoggedOut"), object: nil)
虽然解耦效果好,但用多了容易混乱,记得在dealloc里移除观察者。
全局状态管理
对于复杂的传参需求,比如购物车数量、用户登录状态,可以直接用单例或状态管理工具(如SwiftUI的ObservableObject、Combine等)。哪个页面要用,直接取就行,不用层层传递。
class UserManager {
static let shared = UserManager()
var currentUser: User?
}
// 任意页面访问
let user = UserManager.shared.currentUser
这种方式适合跨模块、高频使用的数据,避免重复传参。