RxSwift (二)序列核心逻辑分析react
RxSwift (三)Observable的建立,订阅,销毁编程
RxSwift(四)高阶函数swift
RxSwift(五)(Rxswift对比swift,oc用法)数组
Rxswift (六)销毁者Dispose源码分析markdown
RxSwift (十) 基础使用篇 1- 序列,订阅,销毁ide
RxSwift学习之十二 (基础使用篇 3- UI控件扩展)函数
@TOCoop
实例1:
复制代码
NotificationCenter.default.rx.notification(UIResponder.keyboardWillShowNotification) .subscribe(onNext: { (noti) in print(noti) }) .disposed(by: disposeBag) 复制代码
实例2:
复制代码
//监听person对象的name的变化 self.person.rx.observeWeakly(String.self, "name") .subscribe(onNext: { (value) in print(value as Any) }) .disposed(by: disposeBag) 复制代码
实例3:
复制代码
let disposeBag = DisposeBag() let tap = UITapGestureRecognizer() self.label.addGestureRecognizer(tap) self.label.isUserInteractionEnabled = true tap.rx.event.subscribe(onNext: { (tap) in print(tap.view) }) .disposed(by: disposeBag) 复制代码
实例4:
复制代码
let url = URL(string: "https://www.baidu.com") URLSession.shared.rx.response(request: URLRequest(url: url!)).subscribe(onNext: { (response,data) in print(response) }, onError: { (error) in print(error) }, onCompleted: { }).disposed(by: disposeBag) 复制代码
实例5:
复制代码
let disposeBag = DisposeBag() var timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance) timer.subscribe(onNext: { (num) in print(num) }) .disposed(by: disposeBag) 复制代码
实例30:
复制代码
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let disposeBag = DisposeBag() override func viewDidLoad() { //建立文本标签 let label = UILabel(frame:CGRect(x:20, y:40, width:300, height:100)) self.view.addSubview(label) //建立一个计时器(每0.1秒发送一个索引数) let timer = Observable<Int>.interval(0.1, scheduler: MainScheduler.instance) //将已过去的时间格式化成想要的字符串,并绑定到label上 timer.map{ String(format: "%0.2d:%0.2d.%0.1d", arguments: [($0 / 600) % 600, ($0 % 600 ) / 10, $0 % 10]) } .bind(to: label.rx.text) .disposed(by: disposeBag) } } 复制代码
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let disposeBag = DisposeBag() override func viewDidLoad() { //建立文本标签 let label = UILabel(frame:CGRect(x:20, y:40, width:300, height:100)) self.view.addSubview(label) //建立一个计时器(每0.1秒发送一个索引数) let timer = Observable<Int>.interval(0.1, scheduler: MainScheduler.instance) //将已过去的时间格式化成想要的字符串,并绑定到label上 timer.map(formatTimeInterval) .bind(to: label.rx.attributedText) .disposed(by: disposeBag) } //将数字转成对应的富文本 func formatTimeInterval(ms: NSInteger) -> NSMutableAttributedString { let string = String(format: "%0.2d:%0.2d.%0.1d", arguments: [(ms / 600) % 600, (ms % 600 ) / 10, ms % 10]) //富文本设置 let attributeString = NSMutableAttributedString(string: string) //从文本0开始6个字符字体HelveticaNeue-Bold,16号 attributeString.addAttribute(NSAttributedStringKey.font, value: UIFont(name: "HelveticaNeue-Bold", size: 16)!, range: NSMakeRange(0, 5)) //设置字体颜色 attributeString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.white, range: NSMakeRange(0, 5)) //设置文字背景颜色 attributeString.addAttribute(NSAttributedStringKey.backgroundColor, value: UIColor.orange, range: NSMakeRange(0, 5)) return attributeString } } 复制代码
实例40:
self.button.addTarget(self, action:#selector(buttonTapped(sender:)), for: UIControlEvents.touchUpInside) @objc func buttonTapped(sender:UIButton?){ } 复制代码
let disposeBag = DisposeBag() //因为tap事件里点击事件用的最多,因此RX默认的tap就是点击事件 self.button.rx.tap .subscribe(onNext: { () in print("点击来了") }) .disposed(by: disposeBag) //RXSwift监听按钮除了点击外的事件: self.button.rx.controlEvent(.touchUpOutside).subscribe(onNext: { () in }) .disposed(by: disposeBag) 复制代码
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let disposeBag = DisposeBag() @IBOutlet weak var button: UIButton! override func viewDidLoad() { //按钮点击响应1 button.rx.tap .subscribe(onNext: { [weak self] in self?.showMessage("按钮被点击") }) .disposed(by: disposeBag) //按钮点击响应2 button.rx.tap .bind { [weak self] in self?.showMessage("按钮被点击") } .disposed(by: disposeBag) // } //按钮标题(title)的绑定 func test1() { //建立一个计时器(每1秒发送一个索引数) let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance) //根据索引数拼接最新的标题,并绑定到button上 timer.map{"计数\($0)"} .bind(to: button.rx.title(for: .normal)) .disposed(by: disposeBag) } //按钮富文本标题(attributedTitle)的绑定 func test2() { //建立一个计时器(每1秒发送一个索引数) let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance) //将已过去的时间格式化成想要的字符串,并绑定到button上 timer.map(formatTimeInterval) .bind(to: button.rx.attributedTitle()) .disposed(by: disposeBag) } //按钮图标(image)的绑定 func test3() { //建立一个计时器(每1秒发送一个索引数) let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance) //根据索引数选择对应的按钮图标,并绑定到button上 timer.map({ let name = $0%2 == 0 ? "back" : "forward" return UIImage(named: name)! }) .bind(to: button.rx.image()) .disposed(by: disposeBag) } //按钮背景图片(backgroundImage)的绑定 func test4() { //建立一个计时器(每1秒发送一个索引数) let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance) //根据索引数选择对应的按钮背景图,并绑定到button上 timer.map{ UIImage(named: "\($0%2)")! } .bind(to: button.rx.backgroundImage()) .disposed(by: disposeBag) } //将数字转成对应的富文本 func formatTimeInterval(ms: NSInteger) -> NSMutableAttributedString { let string = String(format: "%0.2d:%0.2d.%0.1d", arguments: [(ms / 600) % 600, (ms % 600 ) / 10, ms % 10]) //富文本设置 let attributeString = NSMutableAttributedString(string: string) //从文本0开始6个字符字体HelveticaNeue-Bold,16号 attributeString.addAttribute(NSAttributedStringKey.font, value: UIFont(name: "HelveticaNeue-Bold", size: 16)!, range: NSMakeRange(0, 5)) //设置字体颜色 attributeString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.white, range: NSMakeRange(0, 5)) //设置文字背景颜色 attributeString.addAttribute(NSAttributedStringKey.backgroundColor, value: UIColor.orange, range: NSMakeRange(0, 5)) return attributeString } //显示消息提示框 func showMessage(_ text: String) { let alertController = UIAlertController(title: text, message: nil, preferredStyle: .alert) let cancelAction = UIAlertAction(title: "肯定", style: .cancel, handler: nil) alertController.addAction(cancelAction) self.present(alertController, animated: true, completion: nil) } } 复制代码
实例50:
复制代码
复制代码
实例60:
复制代码
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { //分段选择控件 @IBOutlet weak var segmented: UISegmentedControl! //图片显示控件 @IBOutlet weak var imageView: UIImageView! let disposeBag = DisposeBag() override func viewDidLoad() { //建立一个当前须要显示的图片的可观察序列 let showImageObservable: Observable<UIImage> = segmented.rx.selectedSegmentIndex.asObservable().map { let images = ["js.png", "php.png", "react.png"] return UIImage(named: images[$0])! } //把须要显示的图片绑定到 imageView 上 showImageObservable.bind(to: imageView.rx.image) .disposed(by: disposeBag) } func test1() { switch1.rx.isOn.asObservable() .subscribe(onNext: { print("当前开关状态:\($0)") }) .disposed(by: disposeBag) } func test2() { switch1.rx.isOn .bind(to: button1.rx.isEnabled) .disposed(by: disposeBag) } } 复制代码
实例70:
复制代码
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { //分段选择控件 @IBOutlet weak var segmented: UISegmentedControl! //图片显示控件 @IBOutlet weak var imageView: UIImageView! let disposeBag = DisposeBag() override func viewDidLoad() { //建立一个当前须要显示的图片的可观察序列 let showImageObservable: Observable<UIImage> = segmented.rx.selectedSegmentIndex.asObservable().map { let images = ["js.png", "php.png", "react.png"] return UIImage(named: images[$0])! } //把须要显示的图片绑定到 imageView 上 showImageObservable.bind(to: imageView.rx.image) .disposed(by: disposeBag) } func test1() { segmented.rx.selectedSegmentIndex.asObservable() .subscribe(onNext: { print("当前项:\($0)") }) .disposed(by: disposeBag) } } 复制代码
实例80:
复制代码
复制代码
实例90:UITextField使用Rxswift的基本用法
复制代码
self.textFiled.rx.text.orEmpty .subscribe(onNext: { (text) in print(text) }) .disposed(by: disposeBag) // textfiled绑定Button的文字 self.textFiled.rx.text .bind(to: self.button.rx.title()) .disposed(by: disposeBag) 复制代码
实例91:Rxswift监听单个 textField 内容的变化
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let disposeBag = DisposeBag() override func viewDidLoad() { //建立文本输入框 let textField = UITextField(frame: CGRect(x:10, y:80, width:200, height:30)) textField.borderStyle = UITextBorderStyle.roundedRect self.view.addSubview(textField) //当文本框内容改变时,将内容输出到控制台上 textField.rx.text.orEmpty.asObservable() .subscribe(onNext: { print("您输入的是:\($0)") }) .disposed(by: disposeBag) //当文本框内容改变时,将内容输出到控制台上 textField.rx.text.orEmpty.changed .subscribe(onNext: { print("您输入的是:\($0)") }) .disposed(by: disposeBag) } } 复制代码
实例92:Rxswift将textField的内容绑定到其余控件上
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let disposeBag = DisposeBag() override func viewDidLoad() { //建立文本输入框 let inputField = UITextField(frame: CGRect(x:10, y:80, width:200, height:30)) inputField.borderStyle = UITextBorderStyle.roundedRect self.view.addSubview(inputField) //建立文本输出框 let outputField = UITextField(frame: CGRect(x:10, y:150, width:200, height:30)) outputField.borderStyle = UITextBorderStyle.roundedRect self.view.addSubview(outputField) //建立文本标签 let label = UILabel(frame:CGRect(x:20, y:190, width:300, height:30)) self.view.addSubview(label) //建立按钮 let button:UIButton = UIButton(type:.system) button.frame = CGRect(x:20, y:230, width:40, height:30) button.setTitle("提交", for:.normal) self.view.addSubview(button) //当文本框内容改变 let input = inputField.rx.text.orEmpty.asDriver() // 将普通序列转换为 Driver .throttle(0.3) //在主线程中操做,0.3秒内值若屡次改变,取最后一次 //内容绑定到另外一个输入框中 input.drive(outputField.rx.text) .disposed(by: disposeBag) //内容绑定到文本标签中 input.map{ "当前字数:\($0.count)" } .drive(label.rx.text) .disposed(by: disposeBag) //根据内容字数决定按钮是否可用 input.map{ $0.count > 5 } .drive(button.rx.isEnabled) .disposed(by: disposeBag) } } 复制代码
实例93:Rxswift同时监听多个 textField 内容的变化
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let disposeBag = DisposeBag() @IBOutlet weak var textField1: UITextField! @IBOutlet weak var textField2: UITextField! @IBOutlet weak var label: UILabel! override func viewDidLoad() { Observable.combineLatest(textField1.rx.text.orEmpty, textField2.rx.text.orEmpty) { textValue1, textValue2 -> String in return "你输入的号码是:\(textValue1)-\(textValue2)" } .map { $0 } .bind(to: label.rx.text) .disposed(by: disposeBag) } } 复制代码
实例94:Rxswift实现textField事件监听 经过 rx.controlEvent 能够监听输入框的各类事件,且多个事件状态能够自由组合。除了各类 UI 控件都有的 touch 事件外,输入框还有以下几个独有的事件:
editingDidBegin:开始编辑(开始输入内容)
editingChanged:输入内容发生改变
editingDidEnd:结束编辑
editingDidEndOnExit:按下 return 键结束编辑
allEditingEvents:包含前面的全部编辑相关事件
Rxswift代码
textField.rx.controlEvent([.editingDidBegin]) //状态能够组合 .asObservable() .subscribe(onNext: { _ in print("开始编辑内容!") }).disposed(by: disposeBag) 复制代码
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { //用户名输入框 @IBOutlet weak var username: UITextField! //密码输入框 @IBOutlet weak var password: UITextField! let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() //在用户名输入框中按下 return 键 username.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: { [weak self] (_) in self?.password.becomeFirstResponder() }).disposed(by: disposeBag) //在密码输入框中按下 return 键 password.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: { [weak self] (_) in self?.password.resignFirstResponder() }).disposed(by: disposeBag) } } 复制代码
实例95:Rxswift实现textField事件监听
复制代码
实例100:
复制代码
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { let disposeBag = DisposeBag() @IBOutlet weak var textView: UITextView! override func viewDidLoad() { //开始编辑响应 textView.rx.didBeginEditing .subscribe(onNext: { print("开始编辑") }) .disposed(by: disposeBag) //结束编辑响应 textView.rx.didEndEditing .subscribe(onNext: { print("结束编辑") }) .disposed(by: disposeBag) //内容发生变化响应 textView.rx.didChange .subscribe(onNext: { print("内容发生改变") }) .disposed(by: disposeBag) //选中部分变化响应 textView.rx.didChangeSelection .subscribe(onNext: { print("选中部分发生变化") }) .disposed(by: disposeBag) } } 复制代码
//歌曲结构体 struct Music { let name: String //歌名 let singer: String //演唱者 init(name: String, singer: String) { self.name = name self.singer = singer } } //歌曲列表数据源 struct MusicListViewModel { let data = [ Music(name: "无条件", singer: "陈奕迅"), Music(name: "你曾是少年", singer: "S.H.E"), Music(name: "从前的我", singer: "陈洁仪"), Music(name: "在木星", singer: "朴树"), ] } class ViewController: UIViewController { //tableView对象 @IBOutlet weak var tableView: UITableView! //歌曲列表数据源 let musicListViewModel = MusicListViewModel() override func viewDidLoad() { super.viewDidLoad() //设置代理 tableView.dataSource = self tableView.delegate = self } } extension ViewController: UITableViewDataSource { //返回单元格数量 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return musicListViewModel.data.count } //返回对应的单元格 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "musicCell")! let music = musicListViewModel.data[indexPath.row] cell.textLabel?.text = music.name cell.detailTextLabel?.text = music.singer return cell } } extension ViewController: UITableViewDelegate { //单元格点击 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print("你选中的歌曲信息【\(musicListViewModel.data[indexPath.row])】") } } 复制代码
实例111:
/*这里咱们将 data 属性变成一个可观察序列对象(Observable Squence), 而对象当中的内容和咱们以前在数组当中所包含的内容是彻底同样的。 */ //歌曲列表数据源 struct MusicListViewModel { let data = Observable.just([ Music(name: "无条件", singer: "陈奕迅"), Music(name: "你曾是少年", singer: "S.H.E"), Music(name: "从前的我", singer: "陈洁仪"), Music(name: "在木星", singer: "朴树"), ]) } import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { //tableView对象 @IBOutlet weak var tableView: UITableView! //歌曲列表数据源 let musicListViewModel = MusicListViewModel() //负责对象销毁 let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() //将数据源数据绑定到tableView上 musicListViewModel.data .bind(to: /* rx.items(cellIdentifier:):这是 Rx 基于 cellForRowAt 数据源方法的一个封装。 传统方式中咱们还要有个 numberOfRowsInSection 方法, 使用 Rx 后就再也不须要了(Rx 已经帮咱们完成了相关工做)。 */ tableView.rx.items(cellIdentifier:"musicCell")) { _, music, cell in cell.textLabel?.text = music.name cell.detailTextLabel?.text = music.singer }.disposed(by: disposeBag) //tableView点击响应 /* rx.modelSelected: 这是 Rx 基于 UITableView委托回调方法 didSelectRowAt 的一个封装。 */ tableView.rx.modelSelected(Music.self).subscribe(onNext: { music in print("你选中的歌曲信息【\(music)】") }).disposed(by: disposeBag) /*DisposeBag:做用是 Rx 在视图控制器或者其持有者将要销毁的时候, 自动释法掉绑定在它上面的资源。 它是经过相似“订阅处置机制”方式实现(相似于 NotificationCenter 的 removeObserver)。*/ } } 复制代码
实例120:
复制代码
复制代码
实例130:
复制代码
复制代码
实例140:
复制代码
复制代码
实例150:
复制代码
复制代码
实例160:
复制代码
复制代码