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)

至此三种反向传值的方法已经介绍完毕,若有错误或不完善的欢迎大家指正。大家加油!!!

发布了12 篇原创文章 · 获赞 12 · 访问量 536

猜你喜欢

转载自blog.csdn.net/qq_33463449/article/details/103937426