RAC7.0 在Swift项目中的基本使用

https://blog.csdn.net/aluoshiyi/article/details/80844895

2018年06月28日 16:14:41 林升起 阅读数:311

 、集成

在Podfile文件中加入 pod 'ReactiveCocoa', '~> 7.2.0',会自动集成ReactiveCocoa,ReactiveSwift,Result三个库,导入头文件就可以使用了。 

、基本用法

2.1  用户交互

       // 监听文本框输入内容

        accountTextField.reactive.continuousTextValues.observeValues { (text) in

            print("account\(text ?? "")")

        }

        // 监听按钮的点击事件

        loginBtn.reactive.controlEvents(.touchUpInside).observeValues { (button) in

            print("loginBtnClick")

        }

2.2  过滤

 // 当文本的内容长度大于3的时候,才想监听文本的内容

        passwordTextField.reactive.continuousTextValues.filter { (text) -> Bool in

            return text!.count > 3

            }.observeValues { (text) in

     print("accountfilter\(text ?? "")")

        }

2.3    转换

// text的值映射成text的字符数

        textField.reactive.continuousTextValues.map { (text) -> Int in

            return (text?.characters.count)!

            }.filter { (length) -> Bool in

                return length > 5

            }.observe { (length) in

                print(length)

        } 

2.4  冷信号

 func getChatArray() -> SignalProducer<Any, NoError> {

        return SignalProducer<Any, NoError>.init { (observer, _) in

            self.request.GET(url: Host, paras: nil, success: { (request, response) in

                if let response = response {

                    self.dataArray = self.WebArray()

                    observer.send(value: response)

                    observer.sendCompleted()

                }

            }, failure: { (request, error) in

                observer.sendCompleted()

            })

        }

    }

// 创建信号,执行

loadDataAction = Action.init(execute: getChatArray)

        loadDataAction?.apply().start()

// observer 监听

 viewModel.loadDataAction?.events.observe({ (event) in

            print(event)

        })

2.5  热信号


       // 热信号

        let (signalA, observerA) = Signal<String, NoError>.pipe()

        let (signalB, observerB) = Signal<String, NoError>.pipe()

        // 联合信号

        Signal.combineLatest(signalA, signalB).observeValues { (value) in

            print( "收到的值\(value.0) + \(value.1)")

        }

        observerA.send(value: "1")

        //注意:如果加这个就是,发了一次信号就不能再发了

        observerA.sendCompleted()

        observerB.send(value: "2")

        observerB.sendCompleted()

、总结 

知识点:区别冷信号和热信号

Swift中,SignalProducer 对应 RACSignal 为冷信号, Signal 对应的 RACSubject 为热信号。

1.冷信号模式,是被动的,需要有人订阅才开启热信号,热信号是主动的,就算没有订阅者也会即刻推送

热信号可以有多个订阅者,一对多;冷信号只能一对一,当有新的订阅者,信号是重新完整发送的

形象的说:热信号像是直播,冷信号像是点播

2..冷信号个人用来进行网络请求,热信号进行类似代理或者通知的数据传递模式,这样就可以简单的理解为,RAC其实就是把apple的一套 delegate,Notification,KVO等一系列方法综合起来了,用起来更舒服罢了。

 

RAC,ReactiveSwift

1.创建信号

pastedGraphic.png

// 1.通过信号发生器创建(冷信号)

let producer = SignalProducer<String, NoError>.init { (observer, _) in

    print("新的订阅,启动操作")

    observer.send(value: "Hello")

    observer.send(value: "World")

}

 

let subscriber1 = Observer<String, NoError>(value: { print("观察者1接收到值 \($0)") })

let subscriber2 = Observer<String, NoError>(value: { print("观察者2接收到值 \($0)") })

 

print("观察者1订阅信号发生器")

producer.start(subscriber1)

print("观察者2订阅信号发生器")

producer.start(subscriber2)

//注意:发生器将再次启动工作

 

// 2.通过管道创建(热信号)

let (signalA, observerA) = Signal<String, NoError>.pipe()

let (signalB, observerB) = Signal<String, NoError>.pipe()

Signal.combineLatest(signalA, signalB).observeValues { (value) in

    print( "收到的值\(value.0) + \(value.1)")

}

observerA.send(value: "1")

//注意:如果加这个就是,发了一次信号就不能再发了

observerA.sendCompleted()

observerB.send(value: "2")

observerB.sendCompleted()

 

 

//3.创建空信号

let emptySignal = Signal<Any, NoError>.empty

emptySignal.observe { (value) in

    

}

pastedGraphic.png

2.基本控件用法

pastedGraphic.png

//MARK:通知

    private func noti() {

        

        NotificationCenter.default.reactive.notifications(forName: Notification.Name(rawValue: "UIKeyboardWillShowNotification"), object: nil).observeValues { (value) in

            

        }

        

        NotificationCenter.default.post(name: Notification.Name(rawValue: "name"), object: self)

    }

    

    //MARK:KVO

    private func kvoWithRac() {

        

        view.reactive.values(forKeyPath: "bounds").start { [weak self](rect) in

            print(self?.view ?? "")

            print(rect)

        }

    }

    

    //MARK:按钮点击

    private func btnWithRAC() {

        

        //1.点击

        btn.tag = 10

        btn.isEnabled = true

        btn.reactive.controlEvents(.touchUpInside).observeValues { (btn) in

            print("点击了按钮,颜色\(btn.tag)")

        }

    }

 

//textField

textField.reactive.continuousTextValues.observeValues { (value) in

            

        }

pastedGraphic.png

3.过滤  filter

pastedGraphic.png

//filter作用:过滤   当text>5才会输出

        textField.reactive.continuousTextValues.filter { (text) -> Bool in

            

            return (text?.characters.count)! > 5

            }.observe({

                text in

                print(text)

            })

pastedGraphic.png

4.转换 map

pastedGraphic.png

//每一次map接收到的Value事件,它就会运行closure,以closure的返回值作为Value事件发送出去。上面的代码中,我们的text的值映射成text的字符数

        textField.reactive.continuousTextValues.map { (text) -> Int in

            return (text?.characters.count)!

            }.filter { (length) -> Bool in

                return length > 5

            }.observe { (length) in

                print(length)

        }

        

        //(改变属性)使用map与observeValues结合改变属性

        textField.reactive.continuousTextValues

            .map { (text) -> Int in

                return (text?.characters.count)!

            }

            .map { (length) -> UIColor in

                return length > 5 ? UIColor.red : UIColor.yellow

            }

            .observeValues { (backgroundColor) in

                self.textField.backgroundColor = backgroundColor

        }

pastedGraphic.png

5.两个信号结合使用 <~

pastedGraphic.png

//1.

let nameSign = textField.reactive.continuousTextValues.map { (text) -> Int in

            return (text?.characters.count)!

        }

        let passSign = passwordtextField.reactive.continuousTextValues.map { (text) -> Int in

            return (text?.characters.count)!

        }

        btn.reactive.isEnabled <~ Signal.combineLatest(nameSign, passSign).map({(namelength : Int, passlength : Int) -> Bool in

            

            return namelength >= 1 && passlength > 6

        })

 

//2.

Signal.combineLatest(nameSign,passSign).observeValues { (namelength : Int, passlength : Int) in

        }

 

pastedGraphic.png

6.Scheduler(调度器)延时加载

pastedGraphic.png

// 主线程上延时0.3秒调用

        QueueScheduler.main.schedule(after: Date.init(timeIntervalSinceNow: 0.3)) {

            print("主线程调用")

        }

        

        QueueScheduler.init().schedule(after: Date.init(timeIntervalSinceNow: 0.3)){

            print("子线程调用")

        }

pastedGraphic.png

7.迭代器

pastedGraphic.png

// 数组的迭代器

        let array:[String] = ["name","name2"]

        var arrayIterator =  array.makeIterator()

        while let temp = arrayIterator.next() {

            print(temp)

        }

        

        // swift 系统自带的遍历

        array.forEach { (value) in

            print(value)

        }

        

        // 字典的迭代器

        let dict:[String: String] = ["key":"name", "key1":"name1"]

        var dictIterator =  dict.makeIterator()

        while let temp = dictIterator.next() {

            print(temp)

        }

        

        // swift 系统自带的遍历

        dict.forEach { (key, value) in

            print("\(key) + \(value)")

        }

pastedGraphic.png

8.信号联合

pastedGraphic.png

func testZip() {

        let (signalA, observerA) = Signal<Any, NoError>.pipe()

        let (signalB, observerB) = Signal<String, NoError>.pipe()

        

        Signal.zip(signalA, signalB).observeValues { (value) in

            print(value)

        }

        

        signalA.zip(with: signalB).observeValues { (value) in

            

        }

        observerA.send(value: "1")

        observerA.sendCompleted()

        observerB.send(value: "2")

        observerB.sendCompleted()

    }

pastedGraphic.png

9.代替delegate

pastedGraphic.png

1.

import ReactiveCocoa

import ReactiveSwift

import Result

 

2.let (signalTap , observerTap) = Signal<Any, NoError>.pipe()

 observerTap.send(value: tap)

自定义个view

class LyContentView: UIView {

 

    let (signalTap , observerTap) = Signal<Any, NoError>.pipe()

    

    override init(frame: CGRect) {

        super.init(frame: frame)

        

         setUI()

    }

    

    required init?(coder aDecoder: NSCoder) {

        fatalError("init(coder:) has not been implemented")

    }

 

}

 

extension LyContentView {

    fileprivate func setUI() {

        backgroundColor = UIColor.yellow

        

        let tap = UITapGestureRecognizer(target: self, action: #selector(self.tapClick(_:)))

        addGestureRecognizer(tap)

    }

    

    //使用RAC,替代delegate,闭包

    @objc fileprivate func tapClick(_ tap : UITapGestureRecognizer) {

        observerTap.send(value: tap)

    }

}

3.控制器中监听

contentView.signalTap.observeValues { (value) in

            print("点击了view")

        }

pastedGraphic.png

Demo:https://github.com/zhangjie579/LyReactiveSwiftDemo

 

posted @ 2019-03-28 11:42  sundayswift  阅读(1234)  评论(0编辑  收藏  举报