【问题标题】:Toggling a view's visibility from a UIButton, in ReactiveCocoa在 ReactiveCocoa 中从 UIButton 切换视图的可见性
【发布时间】:2014-09-09 14:57:04
【问题描述】:

我的视图中有一个按钮,可以让另一个视图进出动画。菜单按钮可能显示和隐藏菜单的方式相同。这就是我现在拥有的:

- (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 中。我很确定这不是正确的方法。如何更改此设置,以便按钮在隐藏和显示菜单之间交替显示,而不存储状态?

编辑: 好的,我最好的猜测是创建单独的命令来显示和隐藏菜单,然后每次都将另一个命令设置为副作用。很想听听任何更好的想法!

【问题讨论】:

    标签: ios objective-c reactive-cocoa


    【解决方案1】:

    这是一个例子,它可能不是最好的,但我认为值得注意。我经常使用“提升”来删除对自我的引用(因此弱化/强化)......我玩弄了你的代码并得到了这样的工作:

    - (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 的事实有关,因为它不是一个对象。

    我自己还在学习这些东西,但我希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      这是一个更短、更惯用的版本,它结合了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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多