Rxswift (1) Functional responsive programming idea

RxSwift (II) Sequence core logic analysis

Create, subscribe, and destroy an RxSwift Observable

RxSwift (4) higher-order functions

RxSwift (v)

(6) Dispose source code analysis

RxSwift (7) RxSwift vs. SWIFT usage

RxSwift (x) Basic Usage part 1- Sequence, subscribe, destroy

RxSwift Learning 12 (Basics 3- UI Control Extensions)

@TOC

Rxswift common data processing

Target Action

Example 1:

  • Traditional code
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)

func buttonTapped(a) {
    print("button Tapped")}Copy the code
  • Rxswift code
button.rx.tap
    .subscribe(onNext: {
        print("button Tapped")
    })
    .disposed(by: disposeBag)
Copy the code

You don’t need to use Target actions to make the code logic visible.

The agent

Example 2:

  • Traditional code
class ViewController: UIViewController {...override func viewDidLoad(a) {
        super.viewDidLoad()
        scrollView.delegate = self}}extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("contentOffset: \(scrollView.contentOffset)")}}Copy the code
  • Rxswift code
class ViewController: UIViewController {...override func viewDidLoad(a) {
        super.viewDidLoad()

        scrollView.rx.contentOffset
            .subscribe(onNext: { contentOffset in
                print("contentOffset: \(contentOffset)")
            })
            .disposed(by: disposeBag)
    }
}
Copy the code

Rxswift implementation of the proxy, you do not need to write the proxy configuration code, you can get the desired results.

notice

Example 3:

  • Traditional code
var ntfObserver: NSObjectProtocol!

override func viewDidLoad(a) {
    super.viewDidLoad()

    ntfObserver = NotificationCenter.default.addObserver(
          forName: .UIApplicationWillEnterForeground,
          object: nil, queue: nil) { (notification) in
        print("Application Will Enter Foreground")}}deinit {
    NotificationCenter.default.removeObserver(ntfObserver)
}
Copy the code
  • Rxswift code
NotificationCenter.default.rx.notification(UIResponder.keyboardWillShowNotification)
            .subscribe(onNext: { (noti) in
                print(noti)
            })
        .disposed(by: disposeBag)
Copy the code

Back closure

Example 4:

  • Traditional code
URLSession.shared.dataTask(with: URLRequest(url: url)) {
    (data, response, error) in
    guard error == nil else {
        print("Data Task Error: \(error!)")
        return
    }

    guard let data = data else {
        print("Data Task Error: unknown")
        return
    }

    print("Data Task Success with count: \(data.count)")
}.resume()
Copy the code
  • Rxswift code
URLSession.shared.rx.data(request: URLRequest(url: url))
    .subscribe(onNext: { data in
        print("Data Task Success with count: \(data.count)")
    }, onError: { error in
        print("Data Task Error: \(error)")
    })
    .disposed(by: disposeBag)
Copy the code

KVO

Example 5:

  • Traditional code

Copy the code
  • Rxswift code
// Listen for changes in the name of the person object
 self.person.rx.observeWeakly(String.self."name")
            .subscribe(onNext: { (value) in
                print(value as Any)
            })
            .disposed(by: disposeBag)
Copy the code

gestures

Example 6:

  • Traditional code

Copy the code
  • Rxswift code
 let disposeBag = DisposeBag(a)let tap = UITapGestureRecognizer(a)self.label.addGestureRecognizer(tap)
        self.label.isUserInteractionEnabled = true
        tap.rx.event.subscribe(onNext: { (tap) in
            print(tap.view)
        })
        .disposed(by: disposeBag)
Copy the code

The network request

Example 7:

  • Traditional code

Copy the code
  • Rxswift code
 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)
Copy the code

The timer

Example 8:

  • Traditional code

Copy the code
  • Rxswift code
let disposeBag = DisposeBag(a)var timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
        timer.subscribe(onNext: { (num) in
            print(num)
        })
        .disposed(by: disposeBag)
Copy the code

There are dependencies between multiple tasks

Example 9: For example, the Token is obtained through the username and password and then the user information is obtained through the Token

  • Traditional code
// encapsulate the interface with a callback
enum API {

    // get a token by username and password
    static func token(username: String, password: String,
        success: (String) -> Void,
        failure: (Error) - >Void) {... }// Obtain user information through token
    static func userinfo(token: String,
        success: (UserInfo) -> Void,
        failure: (Error) - >Void) {... }}/// Obtain user information by user name and password
API.token(username: "beeth0ven", password: "987654321",
    success: { token in
        API.userInfo(token: token,
            success: { userInfo in
                print("Obtaining user information successfully:\(userInfo)")
            },
            failure: { error in
                print("Failed to obtain user information:\(error)")
        })
    },
    failure: { error in
        print("Failed to obtain user information:\(error)")})Copy the code
  • Rxswift code
// encapsulate the interface with Rx
enum API {

    // get a token by username and password
    static func token(username: String, password: String) -> Observable<String> {... }// Obtain user information through token
    static func userInfo(token: String) -> Observable<UserInfo> {... }}/// Obtain user information by user name and password
API.token(username: "beeth0ven", password: "987654321")
    .flatMapLatest(API.userInfo)
    .subscribe(onNext: { userInfo in
        print("Obtaining user information successfully:\(userInfo)")
    }, onError: { error in
        print("Failed to obtain user information:\(error)")
    })
    .disposed(by: disposeBag)
Copy the code

Wait for multiple concurrent tasks to complete

Example 10: For example, two network requests need to be merged into one

With Rx:

// encapsulate the interface with Rx
enum API {

    /// get the teacher's details
    static func teacher(teacherId: Int) -> Observable<Teacher> {... }/// get the teacher's comment
    static func teacherComments(teacherId: Int) -> Observable"[Comment] > {... }}/// get both teacher information and teacher comments
Observable.zip(
      API.teacher(teacherId: teacherId),
      API.teacherComments(teacherId: teacherId)
    ).subscribe(onNext: { (teacher, comments) in
        print("Success in obtaining teacher information:\(teacher)")
        print("Success in obtaining teacher comments:\(comments.count)Article")
    }, onError: { error in
        print("Failure to obtain teacher information or comment:\(error)")
    })
    .disposed(by: disposeBag)
Copy the code

This allows you to perform fairly complex asynchronous operations in a few lines of code.

Data binding

Example 11:

Let’s compare these two pieces of code:

  1. Traditional code:

Set a single image to the imageView

let image: UIImage = UIImage(named: ...)
imageView.image = image
Copy the code
  1. Rx code:
let image: Observable<UIImage> =... image.bind(to: imageView.rx.image)Copy the code

Rx code: This code “syncs” an image sequence to imageView. Images in this sequence can be generated asynchronously. The image defined here is the blue part of the image above (the listening sequence) and imageView.rx.image is the orange part of the image above (the observer). This “synchronization mechanism” is data binding (subscription).

Rxswift UI usage

UILabel

Examples of 30:

  • Traditional code

Copy the code
  • Rxswift code
  1. Rxswift simply uses UILabel
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
         
        // Create a text label
        let label = UILabel(frame:CGRect(x:20, y:40, width:300, height:100))
        self.view.addSubview(label)
         
        // Create a timer (send an index every 0.1 seconds)
        let timer = Observable<Int>.interval(0.1, scheduler: MainScheduler.instance)
         
        // Formats the elapsed time into the desired string and binds it to the label
        timer.map{ String(format: "% % 0.2 d: % d. 0.2 0.1 d",
                          arguments: [($0 / 600) % 600, ($0 % 600 ) / 10, $0 % 10]) }
        .bind(to: label.rx.text)
        .disposed(by: disposeBag)
    }
}
Copy the code
  1. UILabel Rich Text: Binds data to the attributedText attribute
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
         
        // Create a text label
        let label = UILabel(frame:CGRect(x:20, y:40, width:300, height:100))
        self.view.addSubview(label)
         
        // Create a timer (send an index every 0.1 seconds)
        let timer = Observable<Int>.interval(0.1, scheduler: MainScheduler.instance)
         
        // Formats the elapsed time into the desired string and binds it to the label
        timer.map(formatTimeInterval)
        .bind(to: label.rx.attributedText)
        .disposed(by: disposeBag)
    }
     
    // Convert numbers into corresponding rich text
    func formatTimeInterval(ms: NSInteger) -> NSMutableAttributedString {
        let string = String(format: "% % 0.2 d: % d. 0.2 0.1 d",
                         arguments: [(ms / 600) % 600, (ms % 600 ) / 10, ms % 10])
        // Rich text Settings
        let attributeString = NSMutableAttributedString(string: string)
        // Start from text 0 with 6 character font helveticaneue-bold, size 16
        attributeString.addAttribute(NSAttributedStringKey.font,
                                     value: UIFont(name: "HelveticaNeue-Bold", size: 16)! , range:NSMakeRange(0.5))
        // Set the font color
        attributeString.addAttribute(NSAttributedStringKey.foregroundColor,
                                     value: UIColor.white, range: NSMakeRange(0.5))
        // Set the text background color
        attributeString.addAttribute(NSAttributedStringKey.backgroundColor,
                                     value: UIColor.orange, range: NSMakeRange(0.5))
        return attributeString
    }
}
Copy the code

UIButton

Examples of 40:

  • Traditional code
 self.button.addTarget(self, action:#selector(buttonTapped(sender:)), for: UIControlEvents.touchUpInside)
    @objc func buttonTapped(sender:UIButton?){}Copy the code
  • Rxswift code
 let disposeBag = DisposeBag(a)RX default tap is the tap event, since tap events are used most frequently
 self.button.rx.tap
            .subscribe(onNext: { () in
                print("Click here.")
            })
            .disposed(by: disposeBag)



   //RXSwift listens for events other than button clicks:
    self.button.rx.controlEvent(.touchUpOutside).subscribe(onNext: { () in

        })
            .disposed(by: disposeBag)
Copy the code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag(a)@IBOutlet weak var button: UIButton!
     
    override func viewDidLoad(a) {
        // Button click response 1
        button.rx.tap
            .subscribe(onNext: { [weak self] in
                self? .showMessage("Button clicked")
            })
            .disposed(by: disposeBag)

        // Button click response 2
        button.rx.tap
             .bind { [weak self] in
             self? .showMessage("Button clicked")
               }
               .disposed(by: disposeBag)

//
    }

// The binding of the button title
func test1(a) {
// Create a timer (send an index every 1 second)
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
 
// Concatenate the latest title according to the index number and bind it to the button
timer.map{"Count\ [$0)"}
    .bind(to: button.rx.title(for: .normal))
    .disposed(by: disposeBag)
}

// The binding of the button's attributedTitle
func test2(a) {
 // Create a timer (send an index every 1 second)
        let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
         
        // Format the past time into the desired string and bind it to the button
        timer.map(formatTimeInterval)
            .bind(to: button.rx.attributedTitle())
            .disposed(by: disposeBag)
}

// Bind button icon (image)
func test3(a) {
// Create a timer (send an index every 1 second)
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
 
// Select the corresponding button icon according to the index number and bind it to the button
timer.map({
    let name = $0%2= =0 ? "back" : "forward"
    return UIImage(named: name)!
})
.bind(to: button.rx.image())
.disposed(by: disposeBag)
}

// bind button backgroundImage
func test4(a) {
// Create a timer (send an index every 1 second)
let timer = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
 
// Select the corresponding button background image based on the index number and bind it to the button
timer.map{ UIImage(named: "\ [$0%2)")! }
    .bind(to: button.rx.backgroundImage())
    .disposed(by: disposeBag)
}



// Convert numbers into corresponding rich text
    func formatTimeInterval(ms: NSInteger) -> NSMutableAttributedString {
        let string = String(format: "% % 0.2 d: % d. 0.2 0.1 d",
                            arguments: [(ms / 600) % 600, (ms % 600 ) / 10, ms % 10])
        // Rich text Settings
        let attributeString = NSMutableAttributedString(string: string)
        // Start from text 0 with 6 character font helveticaneue-bold, size 16
        attributeString.addAttribute(NSAttributedStringKey.font,
                                     value: UIFont(name: "HelveticaNeue-Bold", size: 16)! , range:NSMakeRange(0.5))
        // Set the font color
        attributeString.addAttribute(NSAttributedStringKey.foregroundColor,
                                     value: UIColor.white, range: NSMakeRange(0.5))
        // Set the text background color
        attributeString.addAttribute(NSAttributedStringKey.backgroundColor,
                                     value: UIColor.orange, range: NSMakeRange(0.5))
        return attributeString
    }
     
    // Displays a message prompt box
    func showMessage(_ text: String) {
        let alertController = UIAlertController(title: text, message: nil, preferredStyle: .alert)
        let cancelAction = UIAlertAction(title: "Sure", style: .cancel, handler: nil)
        alertController.addAction(cancelAction)
        self.present(alertController, animated: true, completion: nil)}}Copy the code

UIBarButtonItem

Example: 50

  • Traditional code

Copy the code
  • Rxswift code

Copy the code

UISwitch

Example: 60

  • Traditional code

Copy the code
  • Rxswift code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    // segment select control
    @IBOutlet weak var segmented: UISegmentedControl!
    // Image display control
    @IBOutlet weak var imageView: UIImageView!
     
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
        // Create an observable sequence of images that you currently want to display
        let showImageObservable: Observable<UIImage> =
            segmented.rx.selectedSegmentIndex.asObservable().map {
                let images = ["js.png"."php.png"."react.png"]
                return UIImage(named: images[$0])!
        }
         
        // Bind the image to the imageView
        showImageObservable.bind(to: imageView.rx.image)
            .disposed(by: disposeBag)
    }

func test1(a) {
switch1.rx.isOn.asObservable()
    .subscribe(onNext: {
        print("Current switching status:\ [$0)")
    })
    .disposed(by: disposeBag)
}

func test2(a) {
switch1.rx.isOn
    .bind(to: button1.rx.isEnabled)
    .disposed(by: disposeBag)
}
}
Copy the code

UISegmentedControl

Instance, 70:

  • Traditional code

Copy the code
  • Rxswift code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    // segment select control
    @IBOutlet weak var segmented: UISegmentedControl!
    // Image display control
    @IBOutlet weak var imageView: UIImageView!
     
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
        // Create an observable sequence of images that you currently want to display
        let showImageObservable: Observable<UIImage> =
            segmented.rx.selectedSegmentIndex.asObservable().map {
                let images = ["js.png"."php.png"."react.png"]
                return UIImage(named: images[$0])!
        }
         
        // Bind the image to the imageView
        showImageObservable.bind(to: imageView.rx.image)
            .disposed(by: disposeBag)
    }

func test1(a) {
segmented.rx.selectedSegmentIndex.asObservable()
    .subscribe(onNext: {
        print("Current item:\ [$0)")
    })
    .disposed(by: disposeBag)
}
}

Copy the code

UIActivityIndicatorView

Instance, 80:

  • Traditional code

Copy the code
  • Rxswift code

Copy the code

UITextField

Example 90: Basic usage of UITextField using Rxswift

  • Traditional code

Copy the code
  • Rxswift code
self.textFiled.rx.text.orEmpty
            .subscribe(onNext: { (text) in
               print(text)
            })
            .disposed(by: disposeBag)
// TextFiled Bind Button text
self.textFiled.rx.text
            .bind(to: self.button.rx.title())
            .disposed(by: disposeBag)
Copy the code

Example 91: Rxswift listens for changes in the contents of a single textField

  • Rxswift code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
         
        // Create a text input box
        let textField = UITextField(frame: CGRect(x:10, y:80, width:200, height:30))
        textField.borderStyle = UITextBorderStyle.roundedRect
        self.view.addSubview(textField)
         
        // When the content of the text box changes, output the content to the console
        textField.rx.text.orEmpty.asObservable()
            .subscribe(onNext: {
                print("What you typed is:\ [$0)")
            })
            .disposed(by: disposeBag)

// When the content of the text box changes, output the content to the console
textField.rx.text.orEmpty.changed
    .subscribe(onNext: {
        print("What you typed is:\ [$0)")
    })
    .disposed(by: disposeBag)
    
    }
}
Copy the code

Example 92: Rxswift binds the contents of textField to other controls

  • Rxswift code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
         
        // Create a text input box
        let inputField = UITextField(frame: CGRect(x:10, y:80, width:200, height:30))
        inputField.borderStyle = UITextBorderStyle.roundedRect
        self.view.addSubview(inputField)
         
        // Create a text output box
        let outputField = UITextField(frame: CGRect(x:10, y:150, width:200, height:30))
        outputField.borderStyle = UITextBorderStyle.roundedRect
        self.view.addSubview(outputField)
         
        // Create a text label
        let label = UILabel(frame:CGRect(x:20, y:190, width:300, height:30))
        self.view.addSubview(label)
         
        // Create button
        let button:UIButton = UIButton(type:.system)
        button.frame = CGRect(x:20, y:230, width:40, height:30)
        button.setTitle("Submit".for:.normal)
        self.view.addSubview(button)
         
         
        // When the text box content changes
        let input = inputField.rx.text.orEmpty.asDriver() // Convert a normal sequence to a Driver
            .throttle(0.3) // If the value changes several times within 0.3 seconds, take the last time
         
        // The content is bound to another input box
        input.drive(outputField.rx.text)
            .disposed(by: disposeBag)
         
        // The content is bound to the text tag
        input.map{ "Current word count:\ [$0.count)" }
            .drive(label.rx.text)
            .disposed(by: disposeBag)
         
        // Buttons are available based on the number of words
        input.map{$0.count > 5 }
            .drive(button.rx.isEnabled)
            .disposed(by: disposeBag)
    }
}
Copy the code

Example 93: Rxswift listens for changes in the contents of multiple TextFields simultaneously

  • Rxswift code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag(a)@IBOutlet weak var textField1: UITextField!
    @IBOutlet weak var textField2: UITextField!
    @IBOutlet weak var label: UILabel!
     
    override func viewDidLoad(a) {
         
        Observable.combineLatest(textField1.rx.text.orEmpty, textField2.rx.text.orEmpty) {
            textValue1, textValue2 -> String in
            return "The number you typed in was:\(textValue1)-\(textValue2)"}.map{$0 }
            .bind(to: label.rx.text)
            .disposed(by: disposeBag)
    }
}
Copy the code

TextField event listener Rx. ControlEvent Can listen for various events in the input box, and multiple event states can be freely combined. In addition to the touch events common to all UI controls, the input box has the following unique events:

  • EditingDidBegin: Start editing (start typing content)

  • EditingChanged: The input has changed

  • EditingDidEnd: End editing

  • EditingDidEndOnExit: Press the Return key to end editing

  • AllEditingEvents: Contains all previous edit-related events

  • Rxswift code

textField.rx.controlEvent([.editingDidBegin]) // States can be combined
    .asObservable()
    .subscribe(onNext: { _ in
        print("Start editing!")
    }).disposed(by: disposeBag)
Copy the code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
 
    // User name input box
    @IBOutlet weak var username: UITextField!
     
    // Password input box
    @IBOutlet weak var password: UITextField!
     
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
        super.viewDidLoad()
         
        // Press the Return key in the username input field
        username.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: {
            [weak self] (_) in
            self? .password.becomeFirstResponder() }).disposed(by: disposeBag)// Press the return key in the password input box
        password.rx.controlEvent(.editingDidEndOnExit).subscribe(onNext: {
            [weak self] (_) in
            self? .password.resignFirstResponder() }).disposed(by: disposeBag) } }Copy the code

Example 95: Rxswift implements textField event listening

  • Rxswift code

Copy the code

UITextView

Instance, 100:

  • Traditional code

Copy the code
  • Rxswift code
import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
     
    let disposeBag = DisposeBag(a)@IBOutlet weak var textView: UITextView!
     
    override func viewDidLoad(a) {
         
        // Start editing the response
        textView.rx.didBeginEditing
            .subscribe(onNext: {
                print("Start editing")
            })
            .disposed(by: disposeBag)
         
        // Finish editing the response
        textView.rx.didEndEditing
            .subscribe(onNext: {
                print("End of edit")
            })
            .disposed(by: disposeBag)
         
        // The content changes in response
        textView.rx.didChange
            .subscribe(onNext: {
                print("The content has changed")
            })
            .disposed(by: disposeBag)
         
        // Select part of the change response
        textView.rx.didChangeSelection
            .subscribe(onNext: {
                print("The selected part changes.")
            })
            .disposed(by: disposeBag)
    }
}
Copy the code

UITableView

  • Traditional Swift uses UITableView instance 110:
// Song structure
struct Music {
    let name: String / / title
    let singer: String / / singer
     
    init(name: String, singer: String) {
        self.name = name
        self.singer = singer
    }
}

// Song list data source
struct MusicListViewModel {
    let data = [
        Music(name: "Unconditional", singer: Eason Chan),
        Music(name: "You were a teenager.", singer: "S.H.E"),
        Music(name: "The old me.", singer: "Kit Chan"),
        Music(name: "In Jupiter", singer: "Hackberry")]}class ViewController: UIViewController {
 
    / / tableView object
    @IBOutlet weak var tableView: UITableView!
     
    // Song list data source
    let musicListViewModel = MusicListViewModel(a)override func viewDidLoad(a) {
        super.viewDidLoad()
         
        // Set the proxy
        tableView.dataSource = self
        tableView.delegate = self}}extension ViewController: UITableViewDataSource {
    // Returns the number of cells
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return musicListViewModel.data.count
    }
     
    // Returns the corresponding cell
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
        -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "musicCell")!
        letmusic = musicListViewModel.data[indexPath.row] cell.textLabel? .text = music.name cell.detailTextLabel?.text = music.singerreturn cell
    }
}
 
extension ViewController: UITableViewDelegate {
    // Cell click
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Information about the song you selected [\(musicListViewModel.data[indexPath.row])】")}}Copy the code
  • The UITableView Rxswift

Instance, 111:

/* We turn the data property into an Observable Squence, and the contents of the object are exactly the same as they were in the array. * /
// Song list data source
struct MusicListViewModel {
    let data = Observable.just([
        Music(name: "Unconditional", singer: Eason Chan),
        Music(name: "You were a teenager.", singer: "S.H.E"),
        Music(name: "The old me.", singer: "Kit Chan"),
        Music(name: "In Jupiter", singer: "Hackberry"),])}import UIKit
import RxSwift
import RxCocoa
 
class ViewController: UIViewController {
 
    / / tableView object
    @IBOutlet weak var tableView: UITableView!
     
    // Song list data source
    let musicListViewModel = MusicListViewModel(a)// Responsible for object destruction
    let disposeBag = DisposeBag(a)override func viewDidLoad(a) {
        super.viewDidLoad()
         
        // Bind data source data to tableView
        musicListViewModel.data
            .bind(to: 
            /* rx.items(cellIdentifier:) : This is a wrapper around rX based on the cellForRowAt data source method. In the traditional way we also have a numberOfRowsInSection method, which is no longer needed when we use Rx (Rx already does that for us). * / 
       tableView.rx.items(cellIdentifier:"musicCell")) { _, music, cell incell.textLabel? .text = music.name cell.detailTextLabel?.text = music.singer }.disposed(by: disposeBag)//tableView click response
       /* rx.modelSelected: This is a wrapper around RX based on the UITableView delegate callback method didSelectRowAt. * / tableView.rx.modelSelected(Music.self).subscribe(onNext: { music in
            print("Information about the song you selected [\(music)】")
        }).disposed(by: disposeBag)
        /*DisposeBag: Rx automatically interprets the resources bound to the view controller or its owner when it is about to be destroyed. It is implemented through a "subscription disposition mechanism" (similar to removeObserver of NotificationCenter). * /}}Copy the code

UICollectionView

Instance, 120:

  • Traditional code

Copy the code
  • Rxswift code

Copy the code

UIPickerView

Instance, 130:

  • Traditional code

Copy the code
  • Rxswift code

Copy the code

UIDatePicker

Instance, 140:

  • Traditional code

Copy the code
  • Rxswift code

Copy the code

UISlider

Instance, 150:

  • Traditional code

Copy the code
  • Rxswift code

Copy the code

UIStepper

Instance, 160:

  • Traditional code

Copy the code
  • Rxswift code

Copy the code