Как отправить RACSignal в viewMode ячейки при нажатии кнопки за пределами ячеек
У меня есть кнопка на панели навигации, которая называется "Редактировать". И UICollectionView
показать с некоторым содержанием. Нажатие на кнопку "Редактировать" превратит в "Режим редактирования", и название кнопки станет "Готово", UICollectionView
Ячейка также должна обновляться. Нажмите кнопку "Готово", чтобы сделать обратное.
Я написал код ниже: Теперь после нажатия кнопки "Редактировать" | "Готово", представление набора отверстий будет обновлено обновлением, так как в ячейке есть изображения, получаемые из сервиса, которые я не обновляю. Я предпочитаю просто обновить иконку по сигналу Cell. но как рефакторинг кода?
1.viewController - х -(void)viewDidLoad
[[[[self.editButton rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(UIButton *sender) {
if ([sender.titleLabel.text isEqualToString:@"Edit"]) {
[sender setTitle:@"Done" forState:UIControlStateNormal];
}else{
[sender setTitle:@"Edit" forState:UIControlStateNormal];
}
}]
flattenMap:^RACStream *(UIButton *sender) {
BOOL isEditMode = [sender.titleLabel.text isEqualToString:@"Edit"];
return [RACSignal return:@(isEditMode)];
}] subscribeNext:^(NSNumber* x) {
[self.viewModel setEditMode:x.boolValue];
}];
// Binding to view model
[[RACObserve(self.viewModel, dataArray)
deliverOnMainThread] subscribeNext:^(id x) {
@strongify(self);
[self.collectionView reloadData];
}];
2.1.viewController's ViewModel's property
@property (nonatomic, assign, getter= isEditMode) BOOL editMode;
2.2.viewController's ViewModel's -(id)init
self.isEditModeSignal = RACObserve(self, isEditMode);
3.viewController - х - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
DataModel* item = [self.dataArray objectAtIndex:indexPath.row];
[cellViewModel setDataModel:item
withIsEditModeSignal:self.viewModel.isEditModeSignal];
[Cell setCellViewModel:cellViewModel];
4. Клетка ViewModel's -(void)setDataModel:(DataModel)data withIsEditModeSignal:(RACSignal*)isEditModeSignal
self.thing1Signal = [[RACSignal combineLatest:@[self.isEditModeSignal,
other1Signal,
other2Signal]
reduce:^id(NSNumber *isEditMode,
NSNumber *other1,
NSNumber *other2){
return @(isEditMode.boolValue && other1.boolValue && other2.boolValue);
}];
self.thing2Signal = [[RACSignal combineLatest:@[self.isEditModeSignal,
other3Signal,
other4Signal]
reduce:^id(NSNumber *isEditMode,
NSNumber *other3,
NSNumber *other4){
return @(isEditMode.boolValue && other3.boolValue && other4.boolValue);
}];
5.Cell.m - х -(void)setCellViewModel:(CellViewModel*)viewModel
[[[self.viewModel.thing1Signal deliverOnMainThread] takeUntil:self.rac_prepareForReuseSignal] subscribeNext:^(NSNumber *isHidden) {
self.icon1.hidden = isHidden.boolValue;
}];
[[[self.viewModel.thing2Signal deliverOnMainThread] takeUntil:self.rac_prepareForReuseSignal] subscribeNext:^(NSNumber *isHidden) {
self.icon2.hidden = isHidden.boolValue;
}];
2 ответа
Этот код действительно плохой. Вы не используете ReactiveCocoa так, как это было задумано. Лучшим способом является связывание между моделями cellview и viewview. Нет необходимости запускать обновление вообще.
Вот так:
// In cell viewmodel's init method:
RAC(self,isEditMode) = RACObserve(self, collectionViewModel.isEditMode);
//Bind view stuff to: RACObserve(self,isEditMode)
//In collectionview viewmodel init method:
RAC(self,isEditMode) = [[[self.editButton.rac_command executionSignals] flatten] scanWithStart:@NO reduce:id^(NSNumber * running, id next) {
return @(![running boolValue]);
}];
//In collectionview
RAC(self.editButton.titleLabel, text) = [RACObserve(self.viewModel, isEditMode) map:(NSString *)^(NSNumber * x) {
[x boolValue] ? @"Edit" : @"Done";
}];
И вместо того, чтобы использовать combLatest использовать сигнал if.
Ага, нашел проблему: пользуюсь self.isEditModeSignal = RACObserve(self, isEditMode);
Какой я должен использовать self.isEditModeSignal = RACObserve(self, editMode);
, Это коренная причина.