前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ReactiveCocoa 简单用法

ReactiveCocoa 简单用法

作者头像
赵哥窟
发布2020-07-16 17:15:52
8690
发布2020-07-16 17:15:52
举报
文章被收录于专栏:日常技术分享

ReactiveCocoa网上资料很多,今天就介绍一下ReactiveCocoa简单的用法。

监听UITextField的输入文本

在没有使用ReactiveCocoa之前我们监听UITextField文本变化是这样做的

代码语言:javascript
复制
[textField addTarget:self action:@selector(changedTextField:) forControlEvents:UIControlEventEditingChanged];

-(void)changedTextField:(id)textField
{
    NSLog(@"值是---%@",textField.text); 
}

使用了ReactiveCocoa之后就变得简单了

代码语言:javascript
复制
// 监听文本框的输入,而且只有大于3个长度的时候才会打印
[[self.textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
      return value.length > 3;
 }]subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@", x);
 }];
UIButton的点击事件
代码语言:javascript
复制
 [[self.button rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
        NSLog(@"%@", x);
   }];
经典的ReactiveCocoa实现登录

Account

代码语言:javascript
复制
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Account : NSObject

//账号
@property (nonatomic, copy) NSString *userName;

//密码
@property (nonatomic, copy) NSString *password;

@end

NS_ASSUME_NONNULL_END

LoginViewModel.h

代码语言:javascript
复制
#import <Foundation/Foundation.h>
#import "Account.h"

NS_ASSUME_NONNULL_BEGIN

@interface LoginViewModel : NSObject

//用户账号数据模型
@property (nonatomic, strong) Account *account;

// 是否允许登录的信号
@property (nonatomic, strong, readonly) RACSignal *enableLoginSignal;

@property (nonatomic, strong, readonly) RACCommand *LoginCommand;

@end

NS_ASSUME_NONNULL_END

LoginViewModel.m

代码语言:javascript
复制
#import "LoginViewModel.h"

@implementation LoginViewModel


- (Account *)account
{
    if (_account == nil) {
        _account = [[Account alloc] init];
    }
    return _account;
}
- (instancetype)init
{
    if (self = [super init]) {
        [self initialBind];
    }
    return self;
}

// 初始化绑定
- (void)initialBind
{
    // 监听账号的属性值改变,把他们聚合成一个信号。
    _enableLoginSignal = [RACSignal combineLatest:@[RACObserve(self.account, userName),RACObserve(self.account, password)] reduce:^id(NSString *userName,NSString *password){
        return @(userName.length && password.length);

    }];

    // 处理登录业务逻辑
    _LoginCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {

        NSLog(@"点击了登录");
        return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

            // 模仿网络延迟
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

                [subscriber sendNext:@"登录成功"];

                // 数据传送完毕,必须调用完成,否则命令永远处于执行状态
                [subscriber sendCompleted];
            });

            return nil;
        }];
    }];

    // 监听登录产生的数据
    [_LoginCommand.executionSignals.switchToLatest subscribeNext:^(id x) {

        if ([x isEqualToString:@"登录成功"]) {
            NSLog(@"登录成功");
        }
    }];

}

@end

LoginViewController

代码语言:javascript
复制
#import "LoginViewController.h"
#import "LoginViewModel.h"

@interface LoginViewController ()
@property (weak, nonatomic) IBOutlet UITextField *accountField;
@property (weak, nonatomic) IBOutlet UITextField *pwdField;
@property (weak, nonatomic) IBOutlet UIButton *loginBtn;
@property (nonatomic, strong) LoginViewModel *loginViewModel;

@end

@implementation LoginViewController

- (LoginViewModel *)loginViewModel
{
    if (_loginViewModel == nil) {

        _loginViewModel = [[LoginViewModel alloc] init];
    }
    return _loginViewModel;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    [self bindModel];
}

// 视图模型绑定
- (void)bindModel
{
    // 给模型的属性绑定信号
    // 只要账号文本框一改变,就会给account赋值
    RAC(self.loginViewModel.account, userName) = _accountField.rac_textSignal;
    RAC(self.loginViewModel.account, password) = _pwdField.rac_textSignal;

    // 绑定登录按钮
    RAC(self.loginBtn,enabled) = self.loginViewModel.enableLoginSignal;

   // 监听登录按钮点击
    [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {

        // 执行登录事件
        [self.loginViewModel.LoginCommand execute:nil];
    }];
}

一提到ReactiveCocoa就有人会说MVVM,但是单独使用ReactiveCocoa也是可以,不一定有了ReactiveCocoa的就是MVVM。项目中很少使用ReactiveCocoa,之前有人提到使用ReactiveCocoa如果出错了很难定位到代码错误。但是简单的使用还是可以了。比如监听UITextField。按钮点击事件啊。

ReactiveCocoaDemo

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 监听UITextField的输入文本
  • UIButton的点击事件
  • 经典的ReactiveCocoa实现登录
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档