斯威夫特 5
好吧, Matt Price 的答案非常适合传递数据,但我将在最新的Swift 版本中重写它,因为我相信新程序员会因为新的语法和方法/框架而发现它不再具有挑战性,因为原始帖子是在 Objective-C 中.
在视图控制器之间传递数据有多种选择。
- 使用导航控制器推送
- 使用转场
- 使用委托
- 使用通知观察者
- 使用块
我将用最新的 iOS 框架在 Swift 中重写他的逻辑
通过导航控制器推送传递数据:从 ViewControllerA 到 ViewControllerB
步骤 1.在 ViewControllerB 中声明变量
var isSomethingEnabled = false
步骤 2.在 ViewControllerB' ViewDidLoad 方法中打印变量
override func viewDidLoad() {
super.viewDidLoad()
// Print value received through segue, navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA: ", isSomethingEnabled)
}
步骤 3.在 ViewControllerA 中传递数据,同时通过导航控制器推送
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.isSomethingEnabled = true
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
所以这里是完整的代码:
视图控制器A
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: Passing data through navigation PushViewController
@IBAction func goToViewControllerB(_ sender: Any) {
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.isSomethingEnabled = true
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
}
}
视图控制器B
import UIKit
class ViewControllerB: UIViewController {
// MARK: - Variable for Passing Data through Navigation push
var isSomethingEnabled = false
override func viewDidLoad() {
super.viewDidLoad()
// Print value received through navigation push
print("Value of 'isSomethingEnabled' from ViewControllerA: ", isSomethingEnabled)
}
}
通过 Segue 传递数据:从 ViewControllerA 到 ViewControllerB
步骤 1.创建从 ViewControllerA 到 ViewControllerB 的 Segue,并在 Storyboard 中提供 Identifier = showDetailSegue,如下所示
步骤 2.在 ViewControllerB 中声明一个名为isSomethingEnabled的可行对象并打印其值。
步骤 3.在 ViewControllerA 中传递 isSomethingEnabled 的值,同时传递 Segue
所以这里是完整的代码:
视图控制器A
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK: - - Passing Data through Segue - -
@IBAction func goToViewControllerBUsingSegue(_ sender: Any) {
performSegue(withIdentifier: "showDetailSegue", sender: nil)
}
// Segue Delegate Method
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "showDetailSegue") {
let controller = segue.destination as? ViewControllerB
controller?.isSomethingEnabled = true//passing data
}
}
}
视图控制器B
import UIKit
class ViewControllerB: UIViewController {
var isSomethingEnabled = false
override func viewDidLoad() {
super.viewDidLoad()
// Print value received through segue
print("Value of 'isSomethingEnabled' from ViewControllerA: ", isSomethingEnabled)
}
}
通过 Delegate 传递数据:从 ViewControllerB 到 ViewControllerA
步骤 1.在 ViewControllerB 文件中,但在类之外声明协议ViewControllerBDelegate
protocol ViewControllerBDelegate: NSObjectProtocol {
// Classes that adopt this protocol MUST define
// this method -- and hopefully do something in
// that definition.
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}
步骤 2.在 ViewControllerB 中声明 Delegate 变量实例
var delegate: ViewControllerBDelegate?
步骤 3.在 ViewControllerB 的 viewDidLoad 方法中为委托发送数据
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
步骤 4.在 ViewControllerA 中确认 ViewControllerBDelegate
class ViewControllerA: UIViewController, ViewControllerBDelegate {
// to do
}
步骤 5.确认您将在 ViewControllerA 中实现委托
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.delegate = self//confirming delegate
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
步骤 6.在 ViewControllerA 中实现接收数据的委托方法
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
所以这里是完整的代码:
视图控制器A
import UIKit
class ViewControllerA: UIViewController, ViewControllerBDelegate {
override func viewDidLoad() {
super.viewDidLoad()
}
// Delegate method
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?) {
print("Value from ViewControllerB's Delegate", item!)
}
@IBAction func goToViewControllerForDelegate(_ sender: Any) {
if let viewControllerB = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewControllerB") as? ViewControllerB {
viewControllerB.delegate = self
if let navigator = navigationController {
navigator.pushViewController(viewControllerB, animated: true)
}
}
}
}
视图控制器B
import UIKit
//Protocol decleare
protocol ViewControllerBDelegate: NSObjectProtocol {
// Classes that adopt this protocol MUST define
// this method -- and hopefully do something in
// that definition.
func addItemViewController(_ controller: ViewControllerB?, didFinishEnteringItem item: String?)
}
class ViewControllerB: UIViewController {
var delegate: ViewControllerBDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// MARK: - - - - Set Data for Passing Data through Delegate - - - - - -
delegate?.addItemViewController(self, didFinishEnteringItem: "Data for ViewControllerA")
}
}
通过 Notification Observer 传递数据:从 ViewControllerB 到 ViewControllerA
Step 1. 在 ViewControllerB 的通知观察者中设置和发布数据
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
Step 2. 在 ViewControllerA 中添加 Notification Observer
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
Step 3. 在 ViewControllerA 中接收 Notification 数据值
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification: ", notification.object ?? "")
}
所以这里是完整的代码:
视图控制器A
import UIKit
class ViewControllerA: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
// Add observer in controller(s) where you want to receive data
NotificationCenter.default.addObserver(self, selector: #selector(self.methodOfReceivedNotification(notification:)), name: Notification.Name("NotificationIdentifier"), object: nil)
}
// MARK: Method for receiving Data through Post Notification
@objc func methodOfReceivedNotification(notification: Notification) {
print("Value of notification: ", notification.object ?? "")
}
}
视图控制器B
import UIKit
class ViewControllerB: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// MARK:Set data for Passing Data through Post Notification
let objToBeSent = "Test Message from Notification"
NotificationCenter.default.post(name: Notification.Name("NotificationIdentifier"), object: objToBeSent)
}
}
通过块传递数据:从 ViewControllerB 到 ViewControllerA
步骤 1. 在 ViewControllerB 中声明块
var authorizationCompletionBlock:((Bool)->())? = {_ 在}
Step 2. 在 ViewControllerB 中的 block 中设置数据
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
Step 3. 在 ViewControllerA 中接收块数据
// Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is: ", isGranted)
}
所以这里是完整的代码:
视图控制器A
import UIKit
class ViewControllerA: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
// MARK:Method for receiving Data through Block
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "showDetailSegue") {
let controller = segue.destination as? ViewControllerB
controller?.isSomethingEnabled = true
// Receiver Block
controller!.authorizationCompletionBlock = { isGranted in
print("Data received from Block is: ", isGranted)
}
}
}
}
视图控制器B
import UIKit
class ViewControllerB: UIViewController {
// MARK: Variable for Passing Data through Block
var authorizationCompletionBlock:((Bool)->())? = {_ in}
override func viewDidLoad() {
super.viewDidLoad()
// MARK: Set data for Passing Data through Block
if authorizationCompletionBlock != nil
{
authorizationCompletionBlock!(true)
}
}
}
您可以在我的 GitHub 上找到完整的示例应用程序,如果您对此有任何疑问,请告诉我。