swift 反向傳值(通知,代理,閉包)簡單使用

有過OC開發經驗的小夥伴都清楚,常用的反向傳值的方法就是通知,代理和block三種方法。這裏我也不必多說,下邊主要介紹一下swift中這三種傳值方法的書寫,詳情請看Demo

通知

step1: 在傳值VC點擊事件中發送廣播

@objc func confirmAction() {
        //這裏我是用的通知中的userInfo傳的值,但如果是隻用一個值的話,其實也是可以用object直接傳值的
        let dic = ["newText":self.textField.text!]
        let notification = NSNotification.Name(rawValue: "refreshFirstViewNewText")
        NotificationCenter.default.post(name: notification, object: nil, userInfo: dic)
        
        self.dismiss(animated: true, completion: nil)
    }

setp2: 在需要接收傳值的VC中要添加監聽通知的觀察者並實現方法

override func viewDidLoad() {
        super.viewDidLoad()
        ///接受通知的方法
        NotificationCenter.default.addObserver(self, selector: #selector(noticeChangeTextAction(noti:)), name: NSNotification.Name(rawValue: "refreshFirstViewNewText"), object: nil)
    }

實現通知方法

func noticeChangeTextAction(noti: Notification){
        let newLabel: UILabel = self.view.viewWithTag(100) as! UILabel
        guard let tempDic = noti.userInfo else {
            return
        }
        newLabel.text = tempDic["newText"] as? String
}

setp3: (必要的) 在VC銷燬的時候移除觀察者

//移除通知
    deinit {
        NotificationCenter.default.removeObserver(self)
    }

代理模式

step1: 在傳值界面設置協議並添加代理方法

///設置協議
protocol VCDelegate {
    ///代理方法
    func delegateReverseValue(newText:String?)
}

class DelegateViewController: UIViewController {
    ///增加代理屬性
    var delegate: VCDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    @objc func confirmAction() {
        ///判斷是否有遵循的代理
        guard let customDelegate = delegate else {
            return
        }
        customDelegate.delegateReverseValue(newText: textField.text)
        
        self.dismiss(animated: true, completion: nil)
    }
}

step2: 在接收值界面遵循協議比實現代理方法

//遵守協議VCDelegate
class ViewController: UIViewController , VCDelegate{
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //代理傳值
        let delegateButton = UIButton.init(frame: CGRect(x: self.view.bounds.width/2 - 200/2, y: noticeButton.frame.origin.y + 60, width: 200, height: 30))
        delegateButton.setTitle("代理傳值", for: .normal)
        delegateButton.setTitleColor(UIColor.black, for: .normal)
        delegateButton.titleLabel?.font = UIFont.systemFont(ofSize: 15)
        delegateButton.addTarget(self, action: #selector(delegateAction), for: .touchUpInside)
        self.view.addSubview(delegateButton)
}
//MARK: ========== 代理傳值
    //代理按鈕事件
    func delegateAction(){
        
        let newLabel: UILabel = self.view.viewWithTag(100) as! UILabel
        
        let delegateVC = DelegateViewController.init()
        delegateVC.labelText = newLabel.text
        delegateVC.delegate = self //把當前VC設置爲代理
        self.present(delegateVC, animated: true, completion: nil)
        
    }
    //實現代理中的方法
    func delegateReverseValue(newText: String?) {
        let newLabel: UILabel = self.view.viewWithTag(100) as! UILabel
        
        newLabel.text = newText!
    }

閉包

step1: 在修改值的VC創建閉包

    //給閉包起一個別名
    typealias ChangeTextAction = (String) -> ()
    //閉包屬性
    var changeBlock: ChangeTextAction?

setp2: 在傳值VC把新值傳入閉包

    ///判斷閉包是否爲空
    guard let changeBlock = changeBlock else {
        return
    }
    //傳值
    changeBlock(inputValue)
    self.dismiss(animated: true, completion: nil)

step3: 使用值的VC使用值

    let blockVC = BlockViewController.init()
    blockVC.labelText = newLabel.text
        blockVC.changeBlock = { newStr in
        newLabel.text = newStr //替換新值
    }
    self.present(blockVC, animated: true, completion: nil)

至此三種反向傳值的方法已經介紹完畢,若有錯誤或不完善的歡迎大家指正。大家加油!!!

發佈了14 篇原創文章 · 獲贊 13 · 訪問量 2068
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章