KingPolygon
KingPolygon

Reputation: 4755

iOS: Is there a way to get the backgroundColor of every element in a view?

I'm currently trying to create a simple method call in my ViewController such as:

[self greyscale];

Where greyscale is a method in a UIViewController category. What I'm trying to do is using recursion and blocks, I'm trying to gather every element in the ViewController and get their backgroundColor property and then change those values so that it becomes greyScale i.e. [UIColor colorWithWhite:(0.299*red + 0.587*green + 0.114*blue) alpha:alpha];

I've tried the following (so far only for uibuttons):

- (void)runBlockOnAllSubviews:(SubviewBlock)block {

    block(self.view);
    for (UIViewController* viewController in [self.view subviews]) {
        [viewController runBlockOnAllSubviews:block];
    }
}

- (void)greyscale {

    [self runBlockOnAllSubviews:^(UIView *view) {

    if ([view isKindOfClass:[UIButton class]]) {
       [(UIControl *)view setBackgroundColor:[UIColor redColor]];
       [(UIButton *)view setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];
    }
}];

So far setting the background color works, but the problem is I have receiving the current backgroundColor of that element so I can send it to another method that does the "grayscaling" for me, so I can I do something like:

[(UIControl *)view setBackgroundColor:[UIColor greyScaleWith:view.backgroundColor]];

When I tried that it sets it to white because the "view"'s backgroundColor is nil or 0;

Is there a better way to access and change the color of every element on a uiview without making it complicated in the initial ViewController? I would like to do this for greyscale, darkerShade, etc.

Thank you!

Upvotes: 0

Views: 1021

Answers (1)

rdelmar
rdelmar

Reputation: 104082

It's not clear what you're trying to do with blocks in your code; I don't think there's any particular advantage to using blocks to accomplish your task. Also, your first loop (for (UIViewController* viewController in [self.view subviews])) doesn't make sense, because there are no view controllers as subviews of your view. You can change all the colors with a simple recursive method in a category on UIView. I've included a typedef to define different types of color conversions. My example just converts the colors to light gray or gray, so you should substitute whatever algorithm you want in convertColorForView:conversionType: to accomplish your goals. Here's the .h,

typedef NS_ENUM(NSInteger, RDColorConversionType) {
    RDColorConversionTypeGrayScale = 0,
    RDColorConversionTypeDarken,
};

@interface UIView (ColorConversions)

- (void)convertSubviewsBackgroundColor:(RDColorConversionType) type;

The .m file,

@implementation UIView (ColorConversions)

- (void)convertSubviewsBackgroundColor:(RDColorConversionType) type {
    //[self grayScaleForView:self];
    for (UIView *subview in self.subviews) {
        [self convertColorForView:subview conversionType:type]; // delete this line, and uncomment the one above if you want the view that calls this method to have its background color changed too.
        [subview convertSubviewsBackgroundColor:type];
    }
}


-(void)convertColorForView:(UIView *) view conversionType:(RDColorConversionType) type {
    switch (type) {
        case RDColorConversionTypeGrayScale:
            view.backgroundColor = [UIColor lightGrayColor];
            break;
        case RDColorConversionTypeDarken:
            view.backgroundColor = [UIColor grayColor];
            break;
    }

}

You would call this method in your view controller like so,

[self.view convertSubviewsBackgroundColor:RDColorConversionTypeGrayScale];

Upvotes: 1

Related Questions