【问题标题】:Disable all subviews in a IBOutletCollection禁用 IBOutletCollection 中的所有子视图
【发布时间】:2015-12-29 08:29:25
【问题描述】:

我想禁用/启用 IBOutletCollection 中的所有 UIView。 但是 UIView 的类不同,所以我不能直接调用setEnabled

然后我想我会使用performSelector 方法来做到这一点,但是我只能发送一个对象作为参数。

我在本网站和其他网站上都阅读过我可以使用 [NSNumber numberWithBool YES/NO] 的内容,但是在发送带有布尔值 YES 或 NO 的 NSNumber 时,启用状态不会改变。

我使用nil 让禁用的部分工作,但是我找不到将其设置为启用的方法:

-(void) setControlsState: (BOOL) enabled

{
    for(UIView *subview in controls)
    {
        NSNumber *boolObject = enabled? [NSNumber numberWithBool: YES]: nil;
        if([subview respondsToSelector: @selector(setEnabled:)])
        {
            [subview performSelector: @selector(setEnabled:) withObject: boolObject];
        }
        else if([subview respondsToSelector: @selector(setEditable:)])
        {
            [subview performSelector: @selector(setEditable:) withObject: boolObject];
        }
        subview.alpha = enabled? 1: 0.5;
    }
}

其中的控件是由 UISliders、UIButtons、UITextViews 和 UITextfields 组成的 IBOutletCollection。 (@property (strong, nonatomic) IBOutletCollection(UIView) NSArray *controls;)

注意: UITextViews 在上面的代码中可以正常工作,它只是其他类型的 UIViews,它使用setEnabled

【问题讨论】:

    标签: ios selector


    【解决方案1】:

    您是否有特定原因不使用不允许触摸事件的userInteractionEnabled

    -(void) setControlsState: (BOOL) enabled
    {
        for(UIView *aView in controls)
        {
            if ([aView isKindOfClass:[UIView class]]){
                aView.userInteractionEnabled = enabled;
                aView.alpha = (enabled)?1.0:0.5;// Be mindful of this it doesn't seem to respect group opacity. i.e. sliders look funny.
            }
        }
    }
    

    如果有你可以在检查它的类后简单地转换 aView 指针,如下所示:(当然你必须枚举你使用的所有类)

    -(void) setControlsState: (BOOL) enabled
    {
        for(UIView *aView in controls)
        {
            if ([aView isKindOfClass:[UISlider class]]){
                [(UISlider *)aView setEnabled:enabled];
            }
            if ([aView isKindOfClass:[UITextView class]]){
                [(UITextView *)aView setEditable:enabled];
            }
            // and so forth
        }
    }
    

    【讨论】:

    • 酷。如果您实际上不能使用userInteractionEnabled,我对您的代码进行了修改。我想这仅供将来参考。
    【解决方案2】:

    我昨天自己遇到了这个问题。就我而言,设置userInteractionEnabled 是不够的,因为我希望控件显示为灰色,而不仅仅是停止响应触摸事件。我还有一些具有自定义启用/禁用行为的 UIView 子类,我不想像@NJones 建议的那样枚举所有类,以防我将来添加更多控件。

    正如 OP 所指出的,使用 NSNumber 不起作用。解决方案是使用NSInvocation,如 TomSwift 对this question 的回答中所述。我决定把它包装在一个方便的函数中:

    void XYPerformSelectorWithBool(id obj, SEL selector, BOOL boolean)
    {
        NSMethodSignature *signature = [[obj class] instanceMethodSignatureForSelector:selector];
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
        [invocation setSelector:selector];
        [invocation setArgument:&boolean atIndex:2];
        [invocation invokeWithTarget:obj];
    }
    

    那么禁用所有控件就这么简单:

    for (UIView *view in controls)
        if ([view respondsToSelector:@selector(setEnabled:)])
            XYPerformSelectorWithBool(view, @selector(setEnabled:), NO);
    

    【讨论】:

      猜你喜欢
      • 2021-11-20
      • 2013-11-17
      • 1970-01-01
      • 2014-12-16
      • 2011-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多