RxSwift---简单实战(四)

经过前面三篇文章的探索,我们对RxSwift的原理有了一定的认知,正所谓所有的理论基础都是为实践作铺垫的,那么今天我们就来进行一些RxSwift在项目中的实际运用

概况

今天准备了下图中的一些UI控件,根据实际开发中遇到的需求,使用RxSwift完成这些需求

需求一

  • 出生日期不能超过今天,否则UIDatePicker的边框变色

分析:

  • 1.出生日期是一个日期,那么观察的对象就是一个日期date
  • 2.不能超过今天,那么需要一个涮选条件判断是否选择的日期超过今天
  • 3.如果超过今天那么UIDatePicker边框变颜色,这里需要一个映射,超过是一种颜色,没超过是一种颜色

代码如下:

        //出生日期不能超过今天,否则边框变色
        let birthdayOb = birthdayPicker.rx.date
            .map{NSObject.isValidDate(date: $0)} //判断日期是否超过今天
        birthdayOb.map{$0 ? UIColor.red: UIColor.clear} //超过今天返回红色,没超过则无色
            .subscribe { color in
                self.birthdayPicker.layer.borderColor = color.cgColor
            }
            .disposed(by: disposeBag)

//日期是否小于当天
    class func isValidDate(date: Date) -> Bool {
        let calendar = NSCalendar.current
        let compare = calendar.compare(date, to: Date.init(), toGranularity: .day)
        return compare == .orderedDescending
    }

这里的map函数是一个高阶函数,再后面的文章中,会再去探索高阶函数的,这里它就是把一个序列映射成另一个序列

需求二

  • 性别选择

分析:

  • 1.性别选择,两个按钮的单项选择,那么逻辑处理在一起没必要单独处理
  • 2.我们观察的是性别,那么需要创建一个性别的序列
  • 3.male处于选中状态,那么female则是非选中状态
  • 4.按钮是通过点击来改变状态的

代码如下:

        //性别选择
        let genderSeleteOb = BehaviorRelay<MGGender>(value: .notSelected)
        
        maleBtn.rx.tap
            .map{MGGender.male} //男 序列
            .bind(to: genderSeleteOb) //绑定自定义序列
            .disposed(by: disposeBag)
        
        femaleBtn.rx.tap
            .map {MGGender.female} //女 序列
            .bind(to: genderSeleteOb) //绑定自定义序列
            .disposed(by: disposeBag)
        
        genderSeleteOb.subscribe { gender in
            if gender == .notSelected {return}
            let isMale = gender == .male
            self.maleBtn.setImage(UIImage(named: isMale ? "check": "uncheck"), for: .normal)
            self.femaleBtn.setImage(UIImage(named: isMale ? "uncheck": "check"), for: .normal)
        }
        .disposed(by: disposeBag)

BehaviorRelay带默认值的序列,也是一个高阶函数,在后面的文章中会有介绍

需求三

  • 更新按钮的是否可点击,当上面的日期选择不违规且性别已经选择的情况下,更新按钮为可点击状态,否则不可点击

分析

1.性别序列已经生日序列需要绑定在一起

代码如下

        let genderSelOB = genderSeleteOb.map {$0 != .notSelected}

        Observable.combineLatest(birthdayOb, genderSelOB) { !$0 && $1 }
            .bind(to: updateBtn.rx.isEnabled)
            .disposed(by: disposeBag)

combineLatest高阶函数

需求四

  • 1.UISwitch控件打开时,UISlider设置在1/4处,否在位0
  • 2.当Swift掌握程度不为0时,Swiftswitch按钮打开,否则关闭
        /**
         对UISwitch来说:
         当UISwitch为OFF时,表示用户不了解Swift,因此,下面的UISlider应该为0;
         当UISwitch为ON时,可以默认把UISlider设置在1/4的位置,表示大致了解;
         
         对于UISlider来说:
         当UISlider不为0时,应该自动把UISwitch设置为ON;
         当UISlider为0时,应该自动把UISwitch设置为OFF;
         */
        
        knowSwiftSwitch.rx.value.map {$0 ? 0.25 : 0}
            .bind(to: swiftLevelSlider.rx.value)
            .disposed(by: disposeBag)
        
        swiftLevelSlider.rx.value.map {$0 > 0 ? true : false}
            .bind(to: knowSwiftSwitch.rx.value)
            .disposed(by: disposeBag)

需求五

  • 热衷程度控制下面爱心的大小
        //爱心大小
        passionToLearnStepper.rx.value.skip(1)
            .subscribe { value in
                UIView .animate(withDuration: 1) {
                    self.heartHeightConstraint.constant = value * 10
                    self.view.layoutIfNeeded()
                }
            }
            .disposed(by: disposeBag)

说时迟那时快,今天的RxSwift简单实战就介绍到这里啦。小伙伴们可以在项目中赶快用起来吧。别忘了手里的小星星哦~~~~

demo下载地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容