2

I'm trying to improve my object oriented skills and I'm always debating if a class is needed or not.

I have a set of UIColors that I'm constantly using throughout my app in different ViewControllers, I originally started by adding them as constant globals as follow...

import UIKit
// Global COLORS
let myBlueColor = UIColor(red: 62.0/255, green: 174.0/255, blue: 206.0/255, alpha: 1.0)
// more global colors here...
class ViewController1{
   // using my global color
   myButton.layer.borderColor = myBlueColor.CGColor
}


// other viewController
import UIKit
class ViewController2{
   // using my global color again
   myButton2.layer.borderColor = myBlueColor.CGColor
}

But then I decided to created a class to force myself to think in more oriented way like so...

Color Class

import Foundation
import UIKit

class Color {

    var myBlueColor:UIColor{
        get{
          return UIColor(red: 62.0/255, green: 174.0/255, blue: 206.0/255, alpha: 1.0)
        }
    }
    var myLightGrayColor:UIColor{
        get{
            return UIColor(red: 249.0/255, green: 249.0/255, blue: 249.0/255, alpha: 1.0)
        }
    }
    var myGreenColor:UIColor{
        get{
            return UIColor(red: 110.0/255, green: 186.0/255, blue: 64.0/255, alpha: 1.0)
        }
    }
    var myRedColor:UIColor{
        get{
            return UIColor(red: 247.0/255, green: 118.0/255, blue: 113.0/255, alpha: 1.0)
        }
    }
    var myYellowColor:UIColor{
        get{
            return UIColor(red: 255.0/255, green: 190.0/255, blue: 106.0/255, alpha: 1.0)
        }
    }
}

View Controller

import UIKit
class ViewController1{

   private var myColor = Color()

   // some other code here...

   myButton.layer.borderColor = myBlueColor.CGColor
}

Other View Controller

import UIKit
class ViewController1{

   private var myColor = Color()

   // some other code here...

   myButton2.layer.borderColor = myBlueColor.CGColor
}

Is my object oriented a better approach? Ok let me rephrase this, is this even how you would do it in a more object oriented way?

I don't know but my Color class looks weird by just using getters (computed properties).

Any suggestions to improve my code.

EDIT: Not a duplicate because I was interested on improving my object oriented example more than knowing if globals were ok to use.

Thanks

fs_tigre
  • 10,650
  • 13
  • 73
  • 146
  • 1
    Possible duplicate of [Global constants file in Swift](http://stackoverflow.com/questions/26252233/global-constants-file-in-swift) –  Feb 13 '16 at 03:08

3 Answers3

6

Definitely a good idea, but you can probably make it even more clear by just extending UIColor and making those all class functions, exactly the same way as the built-in UIColor.whiteColor(), etc.

You can do that like this:

    extension UIColor {

    class func peachColor() -> UIColor {
        return UIColor(colorLiteralRed: 100.00 / 100.00, green: 92.9 / 100.0, blue: 65.9 / 100.0, alpha: 1.0)
    }
    ...
   }

Then, anywhere in your app, you can say UIColor.peachColor() and it'll work perfectly. These class extensions are a clean way to do it, and it'll allow you to avoid putting a var myColor = Color() in each view controller.

Hasnain ahmad
  • 301
  • 1
  • 10
  • 33
creeperspeak
  • 5,403
  • 1
  • 17
  • 38
  • 1
    Best and easiest implementation – Mihado Feb 13 '16 at 03:55
  • Wow, when I started reading the Swift documentation I actually skip the Extensions section thinking that it was something that I would never use or at least not often but it is a VERY cool feature. Thanks a lot for the tip. For those that have never used extensions, here is what I did. `1. Created a new swift file and named it UIColor 2. Added the color function as described by @creeperspeak 3. Used your custom color as UIColor.myCustomColor()` – fs_tigre Feb 13 '16 at 13:59
1

If you want to encapsulate your Colors in a class, and they will not change, the best way to do so in an OOP environment is by using public static final variables.

(My Swift is very rusty at best so this may be incorrect syntax but it should be clear nonetheless.)

final struct MyColors {
    public static final blue:UIColor = UIColor(red: 62.0/255, green: 174.0/255, blue: 206.0/255, alpha: 1.0)
    // etc
}

You can then reference the value by using MyColors.blue wherever you want, and that will refer to the single defined UIColor object.

CAD97
  • 1,160
  • 12
  • 29
  • I really like this approach too. I don't think `final` can be used in structs though. `import UIKit final class Colors { static let blue:UIColor = UIColor(red: 62.0/255, green: 174.0/255, blue: 206.0/255, alpha: 1.0) }` Thanks a lot for your suggestion. – fs_tigre Feb 13 '16 at 14:28
1

Assuming that you're trying to theme your app globally with colors, you ought to look into Apple's Appearance API, UIAppearance.

For example, to set the default color of all UINavigationBars in your app, you would call:

UINavigationBar.appearance().tintColor = myColor

You can also set other appearance properties such as background images

For more info, see:

http://nshipster.com/uiappearance/ https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIAppearance_Protocol/ https://gist.github.com/mattt/5135521

BergQuester
  • 6,167
  • 27
  • 39