13

I'd like to define a color scheme for my iOS project, in a way that it's easy to replace some colors. Let's say I have a "main" color and a "secondary" color, used in many elements in my app, and in a future I maybe want to set the "main" color to any other value that the one it currently has.

So far I've been using a custom UIColor category to define and use my colors in code, and creating a palette with the same colors for using it in IB and Storyboards.

This way, replacing colors in code is far straightforward, but doing it in IB and Storyboard is so painful... I didn't find an easy way to find/replace colors.

Any idea on how can I manage to do that? I'm open to any suggestion. Thank you in advance

EDIT 1: Maybe it's not clear enough in the question. I'd like to create a scheme such as I can use it both in code and in IB, but defining the colors only once, and being able to switch colors in a way that colors referenced both in code and in IB change accordingly.

sonxurxo
  • 5,648
  • 2
  • 23
  • 33
  • It sounds to me like you want to look at `UIAppearance`. It allows you to change the appearance (things like color and tint) for the whole application. The only drawback is that the theming is not visible from within IB. – David Berry May 01 '14 at 20:14
  • @David I know UIAppearance features, I'm using it in conjunction with my UIColor category. What I don't know, as you mention, is how to do something similar in IB and Storyboards. – sonxurxo May 01 '14 at 20:17
  • I don't think there is a way. You might be able to parse the .storyboard file (it's just complicated xml) and/or patch it with a script. – David Berry May 01 '14 at 20:19
  • I took a look to that file looking for, at least, RGB, HEX or similar codes, but I found that in .storyboard file colors are described with float values for red, green, blue and alpha, or for white and alpha, depending on how you defined them in IB. It's, you know, just a nightmare! – sonxurxo May 01 '14 at 20:22
  • Looks like a job for XSLT to me :) – David Berry May 01 '14 at 20:30
  • any solid comeback to tackle this issue? – Bista Apr 10 '17 at 07:41

2 Answers2

2

You can choose to loop subviews added in the parent view. And can define a set of elements you want to change colors.

So you code might look like below

-(void)defineColors:(UIView *)parent{

    for(UIView *view in parent.subviews){

      if(view.tag == TAG1){
        [self setColor:COLOR1 forControl:view];
      }else if(view.tag == TAG2){
        [self setColor:COLOR2 forControl:view];
      }

    }

}

-(void)setColor:(UIColor *)color forControl:(UIView *)control{

      if([control isKindOfClass:[UILabel class]]){
                [(UILabel *)view setBackgroundColor:color];
      }else if([control isKindOfClass:[UITextField class]]){
                [(UITextField *)view setTextColor:color];
      }

      //So on..


}

I hope it helps.

Cheers.

Code Updated

You can choose to define set of tags for controls you want to assign an specific color, and then set the color accordingly..

Update 2

As per your edited question, you can have a standalone xib in which you can have different small UIView added and you can define colors from xib. Create outlets for different views. And then load the nib in AppDelegate to fetch different colors you want to use you app, and you can save them into a Singleton Class so that you can get them anytime without multiple initializations.

iphonic
  • 12,615
  • 7
  • 60
  • 107
  • Thank you for your quick response, but if you read my question I know how to do that for colors referenced in code. Also, I don't mention that I want to set a color for views depending on its type. Rather, I want to set specific colors to specific views. – sonxurxo May 01 '14 at 19:17
  • @sonxurxo I know that you know how to do stuffs, the solutions I gave has multiple benefits, 1. You don't need to create Outlets 2. You can create set of tags for which you want to set colors.. I will update my code.. – iphonic May 01 '14 at 19:19
  • Maybe a solution based on views' tags would be useful, but I'd like to create a color scheme such as I can use it both in code and in IB – sonxurxo May 01 '14 at 19:21
  • You're absolutely right on that, my mistake. I've reviewed my question and edited it to make it clearer, it was a bit confusing. I think it's now clearer. – sonxurxo May 01 '14 at 19:27
  • 1
    I've upvoted your question since it's an original way to do that, but it does still not solves the problem of referencing colors from IB and Storyboards – sonxurxo May 01 '14 at 19:30
  • @sonxurxo see my `Update 2` – iphonic May 02 '14 at 05:15
  • Yes it's another valid workaround, but it still does not answer my question about how to do it within IB. – sonxurxo May 02 '14 at 06:43
2

An easy way i can do that in Swift:

  • First we have to create as many targets as we want schemes, doing click at actual scheme and select New scheme:

    enter image description here

  • Creating at Assets Catalog Colors Set Colors.xcassets a color like:

    Color at Colors.xcassets

  • Then select one Target membership at Colors.xcassets:

    enter image description here

  • After that create another Colors.xcassets:

    enter image description here

  • Then create again another color with same same at this new Colors.xcassets:

    enter image description here

  • Then select another one Target membership at this new Colors.xcassets:

    enter image description here

  • Then assign color by code using same name referenced (we use PrimaryColor), as in the following example:

    struct Resources {
    
        struct Colors {
            //struct is extended in Colours
        }
    }
    
    extension Colors {
    
        struct Primary {
           static let Default = UIColor(named: "PrimaryColor")!
        }
    }
    
  • And then the implementation:

    newLabel.backgroundColor = Resources.Colors.Primary.Default
    

Finally depending on the scheme chosen, some colors or others will be drawn.

Another way that I have found is next link:

Protocol-Oriented Themes for iOS Apps

Javi AP
  • 392
  • 3
  • 8