你好 RxSwift,應用程序範例

你好 RxSwift!

這是一個 RxSwift 應用程序 - 輸入驗證:

這是一個模擬用戶登陸的程序。html

  • 當用戶輸入用戶名時,若是用戶名不足 5 個字就給出紅色提示語,而且沒法輸入密碼,當用戶名符合要求時才能夠輸入密碼。
  • 一樣的當用戶輸入的密碼不到 5 個字時也給出紅色提示語。
  • 當用戶名和密碼有一個不符合要求時底部的綠色按鈕不可點擊,只有當用戶名和密碼同時有效時按鈕纔可點擊。
  • 當點擊綠色按鈕後彈出一個提示框,這個提示框只是用來作演示而已。

你能夠下載這個例子並在模擬器上運行,這樣能夠幫助於你理解整個程序的交互:git

SimpleValidationFull.gif


### 這個頁面主要由 5 各元素組成:
  1. 用戶名輸入框
  2. 用戶名提示語(紅色)
  3. 密碼輸入框
  4. 密碼提示語(紅色)
  5. 操做按鈕(綠色)
class SimpleValidationViewController : ViewController {

    @IBOutlet weak var usernameOutlet: UITextField!
    @IBOutlet weak var usernameValidOutlet: UILabel!

    @IBOutlet weak var passwordOutlet: UITextField!
    @IBOutlet weak var passwordValidOutlet: UILabel!

    @IBOutlet weak var doSomethingOutlet: UIButton!
    ...
}

複製代碼

### 這裏須要完成 4 個交互:
  • 當用戶名輸入不到 5 個字時顯示提示語,而且沒法輸入密碼github

    image

    override func viewDidLoad() {
        super.viewDidLoad()
    
        ...
    
        // 用戶名是否有效
        let usernameValid = usernameOutlet.rx.text.orEmpty
            // 用戶名 -> 用戶名是否有效
            .map { $0.count >= minimalUsernameLength }
            .share(replay: 1)
    
        ...
    
        // 用戶名是否有效 -> 密碼輸入框是否可用
        usernameValid
            .bind(to: passwordOutlet.rx.isEnabled)  
            .disposed(by: disposeBag)
    
        // 用戶名是否有效 -> 用戶名提示語是否隱藏
        usernameValid
            .bind(to: usernameValidOutlet.rx.isHidden)
            .disposed(by: disposeBag)
    
        ...
    }
    
    複製代碼

    當用戶修改用戶名輸入框的內容時就會產生一個新的用戶名, 而後經過 map 方法將它轉化成用戶名是否有效, 最後經過 bind(to: ...) 來決定密碼輸入框是否可用以及提示語是否隱藏。面試

  • 當密碼輸入不到 5 個字時顯示提示文字算法

    image

    override func viewDidLoad() {
        super.viewDidLoad()
    
        ...
    
        // 密碼是否有效
        let passwordValid = passwordOutlet.rx.text.orEmpty
            // 密碼 -> 密碼是否有效
            .map { $0.count >= minimalPasswordLength }
            .share(replay: 1)
    
        ...
    
        // 密碼是否有效 -> 密碼提示語是否隱藏
        passwordValid
            .bind(to: passwordValidOutlet.rx.isHidden)
            .disposed(by: disposeBag)
    
        ...
    }
    
    複製代碼

    這個和用用戶名來控制提示語的邏輯是同樣的。swift

  • 當用戶名和密碼都符合要求時,綠色按鈕纔可點擊markdown

    image

    override func viewDidLoad() {
        super.viewDidLoad()
    
        ...
    
        // 用戶名是否有效
        let usernameValid = ...
    
        // 密碼是否有效
        let passwordValid = ...
    
        ...
    
        // 全部輸入是否有效
        let everythingValid = Observable.combineLatest(
              usernameValid,
              passwordValid
            ) { $0 && $1 } // 取用戶名和密碼同時有效
            .share(replay: 1)
    
        ...
    
        // 全部輸入是否有效 -> 綠色按鈕是否可點擊
        everythingValid
            .bind(to: doSomethingOutlet.rx.isEnabled)
            .disposed(by: disposeBag)
    
        ...
    }
    
    複製代碼

    經過 Observable.combineLatest(...) { ... } 來將用戶名是否有效以及密碼是都有效合併出二者是否同時有效,而後用它來控制綠色按鈕是否可點擊。網絡

  • 點擊綠色按鈕後,彈出一個提示框多線程

    [圖片上傳失敗...(image-dd32e-1607778397122)]fang'li架構

    override func viewDidLoad() {
        super.viewDidLoad()
    
        ...
    
        // 點擊綠色按鈕 -> 彈出提示框
        doSomethingOutlet.rx.tap
            .subscribe(onNext: { [weak self] in self?.showAlert() })
            .disposed(by: disposeBag)
    }
    
    func showAlert() {
        let alertView = UIAlertView(
            title: "RxExample",
            message: "This is wonderful",
            delegate: nil,
            cancelButtonTitle: "OK"
        )
    
        alertView.show()
    }
    
    複製代碼

    在點擊綠色按鈕後,彈出一個提示框

這樣 4 個交互都完成了,如今咱們縱觀全局看下這個程序是一個什麼樣的結構:

image

而後看一下完整的代碼:

override func viewDidLoad() {
    super.viewDidLoad()

    usernameValidOutlet.text = "Username has to be at least \(minimalUsernameLength) characters"
    passwordValidOutlet.text = "Password has to be at least \(minimalPasswordLength) characters"

    let usernameValid = usernameOutlet.rx.text.orEmpty
        .map { $0.count >= minimalUsernameLength }
        .share(replay: 1)

    let passwordValid = passwordOutlet.rx.text.orEmpty
        .map { $0.count >= minimalPasswordLength }
        .share(replay: 1)

    let everythingValid = Observable.combineLatest(
          usernameValid,
          passwordValid
        ) { $0 && $1 }
        .share(replay: 1)

    usernameValid
        .bind(to: passwordOutlet.rx.isEnabled)
        .disposed(by: disposeBag)

    usernameValid
        .bind(to: usernameValidOutlet.rx.isHidden)
        .disposed(by: disposeBag)

    passwordValid
        .bind(to: passwordValidOutlet.rx.isHidden)
        .disposed(by: disposeBag)

    everythingValid
        .bind(to: doSomethingOutlet.rx.isEnabled)
        .disposed(by: disposeBag)

    doSomethingOutlet.rx.tap
        .subscribe(onNext: { [weak self] in self?.showAlert() })
        .disposed(by: disposeBag)
}

func showAlert() {
    let alertView = UIAlertView(
        title: "RxExample",
        message: "This is wonderful",
        delegate: nil,
        cancelButtonTitle: "OK"
    )

    alertView.show()
}

複製代碼

你會發現你能夠用幾行代碼完成如此複雜的交互。這能夠大大提高咱們的開發效率。

做爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是個人iOS交流圈: 無論你是小白仍是大牛歡迎入駐!! 分享內容包括逆向安防、算法、架構設計、多線程,網絡進階,還有底層、音視頻、Flutter等等......

本身根據梳理網絡來的的開發經驗總結的學習方法,無償分享給你們。更多資源,須要的話均可以自行來獲取下載。 +裙:196800191、 或者是+ WX(XiAZHiGardenia)免費獲取! 獲取面試資料 簡歷模板 一塊兒交流技術

(資源集合)


更多疑問

  • share(replay: 1) 是用來作什麼的?

    咱們用 usernameValid 來控制用戶名提示語是否隱藏以及密碼輸入框是否可用。shareReplay 就是讓他們共享這一個源,而不是爲他們單首創建新的源。這樣能夠減小沒必要要的開支。

  • disposed(by: disposeBag) 是用來作什麼的?

    和咱們所熟悉的對象同樣,每個綁定也是有生命週期的。而且這個綁定是能夠被清除的。disposed(by: disposeBag)就是將綁定的生命週期交給 disposeBag 來管理。當 disposeBag 被釋放的時候,那麼裏面還沒有清除的綁定也就被清除了。這就至關因而在用 ARC 來管理綁定的生命週期。 這個內容會在 Disposable 章節詳細介紹。

相關文章
相關標籤/搜索