swift程序员iOS Developer

iOS页面传值问题(swift2.0篇)

2016-01-10  本文已影响1907人  4ba6804ff45f

iOS页面传值问题(swift2.0篇)

同样是介绍iOS开发中的页面传值,此篇与上一篇使用Objective-C传值对应。在OC中的方法在swift中也是同样适用的,而且还要介绍一些swift特有的方式。

一、协议

使用协议还是3+2一共五个步骤,按部就班来实现就可以了。还是先想清楚谁委托谁代理,在逻辑上不要出现错误。

借用上一篇的图来继续实现各个步骤:


import UIKit

/**
 *    @author kl, 16-01-10 17:01:25
 *
 *    @brief 传值协议
 */
protocol passValueDelegate {
    func passValue(var text: String)
}

class BViewController: UIViewController {
    // 1、声明属性
    var delegate: passValueDelegate?
    
    @IBOutlet weak var textField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    @IBAction func buttonActive(sender: AnyObject) {
        
        // 2、调用代理方法,把值传输出去
        self.delegate?.passValue(textField.text!)
        
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}
import UIKit

class AViewController: UIViewController, passValueDelegate // 1、遵守协议
{

    @IBOutlet weak var textLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()

    }
    
    @IBAction func buttonAction(sender: AnyObject) {
        let bVC = BViewController()
        
        // 2、设置代理
        bVC.delegate = self
        
        self.presentViewController(bVC, animated: true, completion: nil)
        
    }

    // 3、重写协议方法,取到传值
    func passValue(text: String) {
        textLabel.text = text
    }

}

二、闭包

在swift中对闭包有了很好的支持,相当于C和Objective-C的blocks或者Python的lambdas。而且相对于blocks更加灵活一些。这里简单介绍一下使用闭包传递信息的方法。

1、在B类先利用typealias声明一个闭包类型:

typealias nameValue = (String)->Void

2、然后在声明一个此类型的属性:

    var nameText: nameValue?

3、掉用一次闭包属性把值传出去,此处是在Button的跳转方法中调用的:

        // 使用闭包传值出去
        self.nameText!(self.bNameTextField.text!)

4、再添加一个方法用于传值:

    // 闭包方法
    func returnNameValue(name: nameValue) {
        self.nameText = name
    }

1、调用一次A类对象的闭包传值方法拿到值,这里是在Button的跳转方法里调用的:

        // 取到闭包传递的值
        bVC.returnNameValue { (name) -> Void in
            self.nameTextField.text = name
        }

三、使用NSNotificationCenter

在swift语言中通知机制几乎没什么太大变化,还是以NSNotificationCenter为中介者,通过String类型标识来广播和接受信息。一般步骤是广播-接收-移除观察者,最后一步千万不能忘,收到信息记得移除观察者,不然会产生一些意料之外不可预测的情况发生,而且对系统资源也是一种浪费。

1、A发出一个名为"name"的广播,广播内容是A页面上的textField所输入的内容,这里是写在跳转语句后边的,以确保发送的广播是输入完成以后的:

    @IBAction func buttonAction(sender: AnyObject) {
        let bVC = BViewController()
        
        // 取到闭包传递的值
        bVC.returnNameValue { (name) -> Void in
            self.nameTextField.text = name
        }
        
        // 2、设置代理
        bVC.delegate = self
        
        self.presentViewController(bVC, animated: true, completion: nil)
        
        // 发出广播
        NSNotificationCenter.defaultCenter().postNotificationName("name", object: self.nameTextField.text)
    }

2、在B类中接收信息,并在收到时执行指定方法,方法的参数也还是跟Objective-C中一样,第一个为要注册的观察者;第二个同样是SEL类型的参数,不过在swift中没有了@selector关键字,采用以String类型输入要执行的方法名,这个跟OC中是有些区别的;第三个name参数即为要接收的信息的名字,这里采用String类型作为标识;最后一个参数同样是是否指定信息的发送者,填写的话便表示你只需要你填写的那个对象发出的信息,这里nil表示不指定对象:

    override func viewDidLoad() {
        super.viewDidLoad()
        self.bNameTextField.clearButtonMode = .WhileEditing
        self.textField.clearButtonMode = .WhileEditing
        
        // 注册为观察者,接收信息
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "printName:", name: "name", object: nil)
    }
    func printName(notifaction: NSNotification) {
        print(notifaction.object)
        self.bNameTextField.text = notifaction.object as? String
    }

3、在方法中添加移除观察者者的代码:

    func printName(notifaction: NSNotification) {
        print(notifaction.object)
        self.bNameTextField.text = notifaction.object as? String
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

最后还是借用上次的图:


最后的A类文件内容:

import UIKit
class AViewController: UIViewController, passValueDelegate // 1、遵守协议
{
    @IBOutlet weak var textLabel: UILabel!
    @IBOutlet weak var nameTextField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.nameTextField.clearButtonMode = .WhileEditing
    }
        
    @IBAction func buttonAction(sender: AnyObject) {
        let bVC = BViewController()
        
        // 取到闭包传递的值
        bVC.returnNameValue { (name) -> Void in
            self.nameTextField.text = name
        }
        
        // 2、设置代理
        bVC.delegate = self
        
        self.presentViewController(bVC, animated: true, completion: nil)
        
        // 发出广播
        NSNotificationCenter.defaultCenter().postNotificationName("name", object: self.nameTextField.text)
    }
    
    // 3、重写协议方法,取到传值
    func passValue(text: String) {
        textLabel.text = text
    }
    

}
最后的B类文件内容:
import UIKit

protocol passValueDelegate {
    func passValue(var text: String)
}

typealias nameValue = (String)->Void

class BViewController: UIViewController {
    // 1、声明属性
    var delegate: passValueDelegate?
    
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var bNameTextField: UITextField!
    var nameText: nameValue?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.bNameTextField.clearButtonMode = .WhileEditing
        self.textField.clearButtonMode = .WhileEditing
        
        // 注册为观察者,接收信息
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "printName:", name: "name", object: nil)
    }
    
    @IBAction func buttonActive(sender: AnyObject) {
        // 2、调用代理方法,把值传输出去
        self.delegate?.passValue(textField.text!)
        
        // 使用闭包传值出去
        self.nameText!(self.bNameTextField.text!)
        
        self.dismissViewControllerAnimated(true, completion: nil)
    }
    
    func printName(notifaction: NSNotification) {
        print(notifaction.object)
        self.bNameTextField.text = notifaction.object as? String
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    // 闭包方法
    func returnNameValue(name: nameValue) {
        self.nameText = name
    }
}

需要代码戳这里

上一篇 下一篇

猜你喜欢

热点阅读