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)
}
Однако это не поощряется, потому что
- UIKit не соответствует KVO, и если он работает, то это просто случайность.
- Возможно, ваша "правда" не должна быть в пользовательском интерфейсе / кнопке, но у вас должна быть модель, которая определяет, включена кнопка или нет.
С моделью
В этом примере простой 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