我的视图中有一个按钮,可以动画显示另一个视图。菜单按钮可以显示和隐藏菜单的方式相同。这就是我现在所拥有的:
- (void) declareBindings {
self.myButton.rac_command = self.toggleMenuCommand;
}
- (RACCommand *) toggleMenuCommand {
if (!_toggleMenuCommand) {
@weakify(self);
_toggleMenuCommand = [[RACCommand alloc] initWithEnabled:[RACSignal return:@(YES)] signalBlock:^RACSignal *(id sender) {
@strongify(self);
if (!self.menuView.isShowing) {
[self showMenu];
}else{
[self hideMenu];
}
return [RACSignal empty];
}];
}
return _toggleMenuCommand;
}
这个问题是它迫使我在self.menuView.isShowing中存储状态。我很确定这不是正确的做法。如何改变这一点,以便按钮在隐藏和显示菜单之间交替,而不存储状态?
编辑: 好吧,我最好的猜测是创建单独的命令来显示和隐藏菜单,然后每次都将另一个命令设置为副作用。很想听到任何更好的想法!
答案 0 :(得分:3)
这是一个例子,它可能不是最好的,但我认为值得注意。我使用“lift”来删除对self的引用(因此弱化/强化)...我玩了你的代码并得到了类似的东西:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_toggleMenuCommand = [[RACCommand alloc] initWithEnabled:[RACSignal return:@(YES)] signalBlock:^RACSignal *(id sender) {
return [RACSignal return:sender];
}];
RACSignal *menuView = [RACSignal return:self.menuView];
RACSignal *buttonToggled = [_toggleMenuCommand.executionSignals flatten];
RACSignal *changeVisibility = [RACSignal combineLatest:@[buttonToggled, menuView] reduce:^NSNumber *(UIView *button, UIView *menuView) {
return [NSNumber numberWithBool:menuView.hidden];
}];
[self rac_liftSelector:@selector(setMenuVisibility:)
withSignalsFromArray:@[changeVisibility]];
self.myButton.rac_command = _toggleMenuCommand;
}
- (void)setMenuVisibility:(NSNumber *)visible {
self.menuView.hidden = ![visible boolValue];
}
我不确定是否有任何需要解释。实质上,由于每当changeVisibility信号触发时都会有rac_liftSelector
的行,所以广播的消息(对象)将被传递给setMenuVisibility
方法。值得注意的是,所有NSNumber的东西都与我们无法传递BOOL的事实有关,因为它不是一个对象。
我自己还在学习这些东西,但我希望有所帮助。
答案 1 :(得分:3)
以下是使用RACCommand
返回值和RAC
宏的组合的更短且更惯用的版本:
@weakify(self);
RACCommand *toggleMenuCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal *(id input) {
@strongify(self);
return [RACSignal return:@(!self.menuView.hidden)];
}];
self.myButton.rac_command = toggleMenuCommand;
RAC(self.menuView, hidden) = [[toggleMenuCommand executionSignals] flatten];
请注意,[toggleMenuCommand executionSignals]
会返回信号信号,这就是为什么需要flatten
。