简体   繁体   English

禁用IBOutletCollection中的所有子视图

[英]Disable all subviews in a IBOutletCollection

I want to disable/enable all UIViews in a IBOutletCollection. 我想禁用/启用IBOutletCollection中的所有UIView。 However the UIViews differ in class, so I can't call the setEnabled directly. 但是UIViews在类上有所不同,因此我无法直接调用setEnabled

Then I thought I would use the performSelector method to do it, however I can only send an Object as parameter. 然后,我以为可以使用performSelector方法来执行此操作,但是我只能发送一个Object作为参数。

I read both on this site and on other sites that I could just use [NSNumber numberWithBool YES/NO] , however the enabled state doesn't change when sending a NSNumber with either bool YES or NO. 我在本网站以及其他我只能使用[NSNumber numberWithBool YES/NO]网站上都阅读了,但是当发送带有YES或NO的NSNumber时,启用状态不会更改。

I got the disabled part to work by using nil , however I couldn't find a way to set it them enabled: 我通过使用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;
    }
}

Where controls is a IBOutletCollection consisting of UISliders, UIButtons, UITextViews and UITextfields. 控件是一个IBOutletCollection,由UISliders,UIButton,UITextViews和UITextfields组成。 ( @property (strong, nonatomic) IBOutletCollection(UIView) NSArray *controls; ) @property (strong, nonatomic) IBOutletCollection(UIView) NSArray *controls;

Note: The UITextViews works fine wit the above code, it is only the other type of UIViews, which uses setEnabled . 注意: UITextViews与上面的代码可以很好地工作,只是其他类型的UIViews使用setEnabled

Is there a specific reason your not using userInteractionEnabled which disallows touch events? 您没有使用禁止触摸事件的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.
        }
    }
}

If there is you can simply cast the aView pointer after checking it's class, like so: (Of course you'll have to enumerate through all the classes you use) 如果有,您可以在检查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
    }
}

I came up against this problem myself yesterday. 我昨天自己遇到了这个问题。 In my case, setting userInteractionEnabled wasn't sufficient, because I wanted the controls to appear greyed out, not just stop responding to touch events. 就我而言,仅设置userInteractionEnabled是不够的,因为我希望控件显示为灰色,而不仅仅是停止响应触摸事件。 I also had some UIView subclasses with custom enabled/disabled behavior, and I didn't want to have to enumerate all classes as @NJones suggested in case I add more controls in the future. 我也有一些具有自定义启用/禁用行为的UIView子类,并且我不想像@NJones那样枚举所有类,以防将来我添加更多控件。

As the OP noted, using NSNumber does not work. 如OP所述,使用NSNumber不起作用。 The solution is to use NSInvocation as explained in TomSwift's answer to this question . 解决方案是使用NSInvocation如TomSwift对这个问题的回答中所述。 I decided to wrap this in a convenience function: 我决定将其包装在便捷函数中:

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];
}

Then disabling all controls is as simple as: 然后禁用所有控件很简单:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM