Swift — связанное значение или расширение для Enum

Общий вопрос о быстром перечислении.

Я хочу создать перечисление «значок» и «связать» значение с регистром перечисления

enum Icon {
  case plane
  case arrow
  case logo
  case flag
}

Я хочу создать связанное изображение со значением перечисления. А также связанный цвет со значением перечисления

Так, например, если бы можно было сделать что-то вроде:

extension Icon.plane {
  var image = {
    get {
       return UIImage("plane.png")
    }
  }
  var color = {
    get {
       return UIColor.greenColor()
    }
  }
}


var image = Icon.arrow.image // the image associated to the enum
var color = Icon.arrow.color // the color associated to the enum

Возможен ли такой тип вещей?


person Avner Barr    schedule 28.04.2015    source источник


Ответы (4)


К сожалению, вы не можете определить статические свойства на основе случаев перечисления, но вы можете использовать вычисляемые свойства и switch для возврата значений для каждого случая:

enum Icon {
    case plane
    case arrow
    case logo
    case flag

    var image: UIImage {
        switch self {
            case .plane: return UIImage(named: "plane.png")!
            case .arrow: return UIImage(named: "arrow.png")!
            case .logo: return UIImage(named: "logo.png")!
            case .flag: return UIImage(named: "flag.png")!
        }
    }

    var color: UIColor {
        switch self {
        case .plane: return UIColor.greenColor()
        case .arrow: return UIColor.greenColor()
        case .logo: return UIColor.greenColor()
        case .flag: return UIColor.greenColor()
        }
    }
}

// usage
Icon.plane.color
person Kirsteins    schedule 28.04.2015

Используя перечисления со связанными значениями в сочетании с операторами switch, вы можете быть очень гибкими. Первый пример:

enum Icon {
    case plane(img:UIImage, col:UIColor)
    case arrow(img:UIImage, col:UIColor)
    case logo(img:UIImage, col:UIColor)
    case flag(img:UIImage, col:UIColor)

    var values:(img:UIImage,col:UIColor) {
        switch self {
        case let .plane(image, color):
            return (image,color)
        case let .arrow(image, color):
            return (image,color)
        case let .logo(image, color):
            return (image,color)
        case let .flag(image, color):
            return (image,color)
        }
    }
}



var a = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())

a.values.col
a.values.img

и второй пример:

enum Icon {
    case plane(img:UIImage, col:UIColor)
    case arrow(img:UIImage, col:UIColor)
    case logo(img:UIImage, col:UIColor)
    case flag(img:UIImage, col:UIColor)

    var img:UIImage {
        switch self {
        case let .plane(image, color):
            return image
        case let .arrow(image, color):
            return image
        case let .logo(image, color):
            return image
        case let .flag(image, color):
            return image
        }
    }

    var col:UIColor {
        switch self {
        case let .plane(image, color):
            return color
        case let .arrow(image, color):
            return color
        case let .logo(image, color):
            return color
        case let .flag(image, color):
            return color
        }
    }
}



var a = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())

a.col
a.img

нет необходимости в расширениях. И если вам действительно нужны статические значения, вы можете сделать это:

struct MyIcon {
    static let plane = Icon.plane(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
    static let arrow = Icon.arrow(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
    static let logo = Icon.logo(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
    static let flag = Icon.flag(img: UIImage(named: "image.png")!, col: UIColor.blueColor())
}

MyIcon.arrow.col

что может быть более аккуратно, чем размещение фиксированных литеральных значений внутри оператора switch.

person sketchyTech    schedule 28.04.2015

Более короткий и безопасный код:

import UIKit

enum Icon: String {

    case plane, arrow, logo, flag

    var image: UIImage {

        // If the image is not available, provide a default value so we dont force optional unwrapping
        return UIImage(named: "\(self.rawValue).png") ?? UIImage()
    }

    var color: UIColor {
        switch self {
        case .plane: return UIColor.green
        case .arrow: return UIColor.green
        case .logo: return UIColor.green
        case .flag: return UIColor.green
        }
    }
}

// Usage
Icon.plane.color
Icon.arrow.image
person Sam    schedule 24.11.2019

Чище и читабельнее

enum Icon {
    case plane
    case arrow
    case logo
    case flag

    var image: UIImage {
        return value.image
    }

    var color: UIColor {
        return value.color
    }

    private var value: (image: UIImage, color: UIColor) {
        switch self {
        case .plane: return (UIImage(named: "plane.png")!, UIColor.green)
        case .arrow: return (UIImage(named: "arrow.png")!, UIColor.green)
        case .logo: return (UIImage(named: "logo.png")!, UIColor.green)
        case .flag: return (UIImage(named: "flag.png")!, UIColor.green)
        }
    }
}

// Use
Icon.plane.image
Icon.plane.color
person yasinkbas    schedule 02.03.2020