RACObserve(object, keyPath) в ReactiveCocoa 5.0

Я хочу контролировать свойство UIButton.enabled, чтобы изменить button.titleColor

Я сделал в OC, как это:

#import "ViewController.h"
#import <ReactiveCocoa/ReactiveCocoa.h>

@interface ViewController () <UITextViewDelegate>

@property (weak, nonatomic) IBOutlet UIButton *btn;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self initUI];
}

- (void)initUI {

   __weak typeof(self) weakSelf = self;
   [[RACObserve(self.btn, enabled) map:^id(id value) {
    return [value boolValue] ? [UIColor greenColor] : [UIColor redColor];
   }] subscribeNext:^(id x) {
      [weakSelf.btn setTitleColor:x forState:UIControlStateNormal];
   }];

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
     self.btn.enabled = !self.btn.enabled;
}

@end

Теперь я пытаюсь достичь той же цели в быстром использовании последней версии ReactiveCocoa, как это сделать?

1 ответ

Решение

ReactiveCocoa 5.0 добавит расширения UIKit.

С button.reactive.values(forKeyPath:)

Это работает для меня на простой игровой площадке:

button.reactive.values(forKeyPath: "enabled")
    .map { $0 as? Bool }
    .skipNil()
    .map { enabled in enabled ? UIColor.blue : UIColor.red }
    .startWithValues { [weak button = button] color in
        button?.setTitleColor(color, for: .normal)
    }

Однако это не поощряется, потому что

  1. UIKit не соответствует KVO, и если он работает, то это просто случайность.
  2. Возможно, ваша "правда" не должна быть в пользовательском интерфейсе / кнопке, но у вас должна быть модель, которая определяет, включена кнопка или нет.

С моделью

В этом примере простой MutableProperty используется в качестве модели, это может быть в ViewModel или где-либо еще

let buttonEnabled = MutableProperty<Bool>(false)

button.reactive.isEnabled <~ buttonEnabled
buttonEnabled.producer
    .map { enabled in enabled ? UIColor.blue : UIColor.red }
    .startWithValues { [weak button = button] color in
        button?.setTitleColor(color, for: .normal)
    }

К сожалению, вы не можете привязать непосредственно к цвету заголовка кнопки, как вы можете с isEnabled

Другие вопросы по тегам