iOS 屏幕间数据传输:完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

iOS 屏幕间数据传输:从新手到专家

\n\n

每个刚开始为 iOS 编写代码的人,迟早都会遇到一个难题:“如何将字符串、数组或对象传递到另一个屏幕?”这个问题非常普遍,以至于在 Stack Overflow 上它获得了数千次浏览和数十种答案。这并非偶然——iOS 的架构设计使得每个屏幕(ViewController)都独立运行,数据需要在它们之间有意识地传递。

\n\n

在本文中,我们将探讨在 Swift 中视图控制器之间传输数据的 5 种主要方法。您将了解何时使用 segue,何时使用委托或闭包,以及为什么 NotificationCenter 并不总是坏事。开始吧!

\n\n

为什么这会是问题?

\n

iOS 使用严格的 MVC(Model-View-Controller)架构。每个 ViewController 负责其屏幕的一部分,并且无法直接访问相邻控制器的数据。这是为了安全性和模块化而设计的,但对于开发者来说,这意味着需要显式地将数据从点 A“传递”到点 B。

\n\n

想象一下:您有一个用户列表,并且希望在点击某个单元格时显示详细信息。您点击——新屏幕打开。如何传递用户 ID?这就是魔法的开始。

\n\n

方法 1:通过 Storyboard Segue 传输数据(最简单)

\n

最直接的方法是使用 prepare(for:sender:)。您只需在跳转前准备数据。非常适合简单的应用程序和原型。

\n\n
// 在源 ViewController 中\noverride func prepare(for segue: UIStoryboardSegue, sender: Any?) {\n    if segue.identifier == "showDetail" {\n        guard let destinationVC = segue.destination as? DetailViewController else { return }\n        destinationVC.userID = 42 // 传递数字\n        destinationVC.userName = "安娜" // 传递字符串\n    }\n}\n\n// 在 DetailViewController 中\nvar userID: Int = 0\nvar userName: String = ""\n
\n\n

优点: 代码最少,所有内容集中在一处。 缺点: 与 Storyboard 紧密耦合,难以测试,容易在标识符中混淆。

\n\n

方法 2:程序化导航与数据传输(进阶)

\n

当您厌倦了 segues 并希望从代码中完全控制时,请使用控制器的直接实例。

\n\n
// 在源 ViewController 中\nfunc showDetail() {\n    let storyboard = UIStoryboard(name: "Main", bundle: nil)\n    guard let detailVC = storyboard.instantiateViewController(withIdentifier: "DetailVC") as? DetailViewController else { return }\n    \n    detailVC.userID = 42\n    detailVC.userName = "安娜"\n    \n    navigationController?.pushViewController(detailVC, animated: true)\n}\n
\n\n

这种方法提供了完全控制:您可以从网络加载数据、验证数据,然后再跳转。非常适合复杂逻辑。

\n\n

方法 3:委托(Delegate Pattern)——反向通信

\n

如果需要将数据传回怎么办?例如,用户在第二个屏幕上选择了日期,我们希望将其返回到第一个屏幕。这时委托就派上用场了。

\n\n

步骤 1:创建协议

\n
protocol DatePickerDelegate: AnyObject {\n    func didSelectDate(_ date: Date)\n}\n
\n\n

步骤 2:在子控制器中添加委托

\n
class DatePickerViewController: UIViewController {\n    weak var delegate: DatePickerDelegate?\n    \n    @IBAction func saveButtonTapped(_ sender: UIButton) {\n        let selectedDate = datePicker.date\n        delegate?.didSelectDate(selectedDate)\n        dismiss(animated: true)\n    }\n}\n
\n\n

步骤 3:在父控制器中实现委托

\n
class MainViewController: UIViewController, DatePickerDelegate {\n    func didSelectDate(_ date: Date) {\n        print("收到日期: \\(date)")\n        // 更新 UI\n    }\n    \n    override f                

博客

书籍推荐