禁用IBOutletCollection中的所有子视图

时间:2012-01-23 21:46:05

标签: ios selector

我想在IBOutletCollection中禁用/启用所有UIViews。 但是UIViews在课堂上有所不同,所以我不能直接调用setEnabled

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

我在本网站和其他网站上都可以使用[NSNumber numberWithBool YES/NO]阅读,但是当发送带有bool 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可以正常使用上面的代码,它只是使用setEnabled的其他类型的UIViews。

2 个答案:

答案 0 :(得分: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
    }
}

答案 1 :(得分:0)

我昨天亲自反对这个问题。在我的情况下,设置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);