Apr 08, 2016:  ~ 2 min read

Setting variables with tuples, switches and closures

Let's say we have a custom UILabel, which in turn has several types; maybe a StatusLabel that can be of type sold out and expired. The label would have several common properties, but each type would have something specific. How can we go about this?

class StatusLabel: UILabel {
  enum StatusType {
    case soldOut 
    case expired
  init(type: StatusType) {
    super.init(frame: .zero)
    font = UIFont.common
    layer.cornerRadius = 4
    textAlignment = .center
    translatesAutoresizingMaskIntoConstraints = false

We now covered the common parts, and we could go ahead and set the backgroundColor and textColor like this:

switch type {
case .soldOut:
  tag             = ViewTag.soldOutLabel.rawValue
  backgroundColor = .black
  textColor       = .white
case .expired:
  tag             = ViewTag.expiredLabel.rawValue
  backgroundColor = .white
  textColor       = .red

Nothing too ugly so far, but it's already clear that if we'll need to add more cases in the future, the amount of code will drastically increase. Instead, we can make use of tuples and closures:

(tag, backgroundColor, textColor) = { _ -> (Int, UIColor, UIColor) in
  switch type {
  case .soldOut: return (ViewTag.soldOutLabel.rawValue, .black, .white
  case .expired: return (ViewTag.expiredLabel.rawValue, .white, .red)

A bit more compact, and easier to scan columns for the differences. On the other hand, it's also clear that if there are too many different properties between different types, or if 4/5 types have one value for a property, but the 5th is different, this approach stops being as elegant or feasible.

Subscribe to my monthly newsletter.
No spam, unsubscribe at any time.