0

I wish to pick change the background Color of my swift application by calling a random Color from a predetermined string array such as (red, green, pink).

so i have that array and i want the background color to be randomly selected as one of thoses colors.

using self.bg.background color resulted in xcode saying that a string could not be converted into a uicolor

rmaddy
  • 314,917
  • 42
  • 532
  • 579

2 Answers2

1

Here's an example of one way to do this:

import UIKit

extension Array {
  func randomElement() -> Element {
    return self[Int(arc4random_uniform(UInt32(self.count)))]
  }
}

extension UIColor {
  enum ColorEnum: String {
    case red   // = "red"
    case green // = "green"
    case blue  // = "blue"
    case pink  // = "pink"

    func toColor() -> UIColor {
      switch self {
      case .red:
        return .redColor()
      case .green:
        return .greenColor()
      case .blue:
        return .blueColor()
      case .pink:
        return UIColor(hue: 1.0, saturation: 0.25, brightness: 1.0, alpha: 1.0)
      }
    }
  }

  static func fromString(name: String) -> UIColor? {
    return ColorEnum(rawValue: name)?.toColor()
  }
}

let colors = ["red", "green", "pink"] // stored as String
UIColor.fromString(colors.randomElement())

let enumColors: [UIColor.ColorEnum] = [.red, .green, .pink] // stored as enum
enumColors.randomElement().toColor()
  • 1
    @LeoDabus Ahh right, forgot about that shortcut! I'll edit it. –  Jan 25 '16 at 01:53
  • Just wondering what should be called as the uicolor once this has been set up? I was using self.view.backgroundcolor = enumColors however this did not work. sorry if its a simple question i am very new to coding. –  Jan 25 '16 at 08:33
  • The extension should be made on `Indexable` though – DeFrenZ Jan 25 '16 at 11:20
  • @DavideDeFranceschi Yes, it could be made on `Indexable` for the best reuse. I chose not to do that for the sake of clarity in this answer. –  Jan 25 '16 at 13:22
  • @PeterGaffney `enumColors` is just there to show how to store and use an array of enums rather than an array of strings. You would want to use `self.view.backgroundColor = UIColor.fromString(colors.randomElement())`. –  Jan 25 '16 at 13:25
  • oh thanks it know, rally appreciate the help on this. –  Jan 25 '16 at 23:48
  • If this were to be applied so that the same color did not repeat itself how would this be achieved? –  Jan 31 '16 at 00:48
  • @PeterGaffney The easiest way is to randomize an array, pick the first item, then remove it from the array. [Here's a post](http://stackoverflow.com/a/24029847/887210) that shows how to shuffle an array. –  Jan 31 '16 at 04:52
  • Thanks thats perfect –  Feb 01 '16 at 20:35
  • @PeterGaffney No problem, glad to help. –  Feb 01 '16 at 20:37
0

You can't directly convert any string like "Green" "Pink" to UIColor objects. If you want to use only this, then you have to create your custom enum matching these string to there equivalent UIColor objects.

Mean while you can use string color in below forms which are supported by UIColor extension written by me.

  1. RGBA String (String must be separated by space "0.5 0.6 0.7 1.0" 50% of Red 60% of Green 70% of Blue Alpha 100%)
  2. Hexadecimal String for e.g. #ffffff (equivalent of White color) is equal to UIColor.white

To convert these two color string to UIColor you can use following extension of UIColor

extension UIColor {


//Convert RGBA String to UIColor object
//"rgbaString" must be separated by space "0.5 0.6 0.7 1.0" 50% of Red 60% of Green 70% of Blue Alpha 100%
public convenience init?(rgbaString : String){
    self.init(ciColor: CIColor(string: rgbaString))
}

//Convert UIColor to RGBA String
func toRGBAString()-> String {

    var r: CGFloat = 0
    var g: CGFloat = 0
    var b: CGFloat = 0
    var a: CGFloat = 0
    self.getRed(&r, green: &g, blue: &b, alpha: &a)
    return "\(r) \(g) \(b) \(a)"

}
//return UIColor from Hexadecimal Color string
public convenience init?(hexString: String) {

        let r, g, b, a: CGFloat

        if hexString.hasPrefix("#") {
            let start = hexString.index(hexString.startIndex, offsetBy: 1)
            let hexColor = hexString.substring(from: start)

            if hexColor.characters.count == 8 {
                let scanner = Scanner(string: hexColor)
                var hexNumber: UInt64 = 0

                if scanner.scanHexInt64(&hexNumber) {
                    r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
                    g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
                    b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
                    a = CGFloat(hexNumber & 0x000000ff) / 255
                    self.init(red: r, green: g, blue: b, alpha: a)
                    return
                }
            }
        }

        return nil
    }
// Convert UIColor to Hexadecimal String
func toHexString() -> String {
    var r: CGFloat = 0
    var g: CGFloat = 0
    var b: CGFloat = 0
    var a: CGFloat = 0
    self.getRed(&r, green: &g, blue: &b, alpha: &a)
    return String(
        format: "%02X%02X%02X",
        Int(r * 0xff),
        Int(g * 0xff),
        Int(b * 0xff)
    )
}

}

To fetch any random value present in the Array you can create an extension on Array as follows.

extension Array {
   func randomElement() -> Element {
        return self[Int(arc4random_uniform(UInt32(self.count)))]
   }
}

For your case you can create Array of UIColor as follows

   //Define array to hold UIColor which will hold your Views background color  
    var arrOfColors = [UIColor]()

   //Create array of   RGBA String color like
    let arrRGBAStringColor = ["0.5 0.6 0.7 1.0","0.53 0.46 0.27 1.0","0.3 0.16 0.17 1.0"]

   //Create array of   Hexadecimal String color like
    let arrHexStringColor = ["#cccc41","#8e8e8e","#003300"]


    for stringColor in arrRGBAStringColor {

        //Use UIColor extension to convert RGBA string to UIColor
        if let color = UIColor(rgbaString : stringColor){
            arrOfColors.append(color)
        }
    }
    for stringColor in arrHexStringColor {
        //Use UIColor extension to convert Hexadecimal string to UIColor
        if let color = UIColor(hexString : stringColor){
            arrOfColors.append(color)
        }
    }

    //Now fetch any random color from your color array
    let randomColor = arrOfColors.randomElement()

    self.backgroundColor = randomColor
Sudhir kumar
  • 659
  • 5
  • 21