【问题标题】:Add a custom palette to IB that propagates if a color changes iOS将自定义调色板添加到 IB,如果颜色更改 iOS 则会传播
【发布时间】:2017-04-14 13:22:38
【问题描述】:

我想在 IB 中创建一个自定义调色板,您可以在其中设置颜色,如果该调色板中的颜色发生变化,它会通过视图传播。我见过这种方法http://natashatherobot.com/xcode-color-palette/,但是如果将来调色板的颜色发生变化,您必须转到项目的每个视图并更改该颜色。我也试过做一个@IBInspectable,但你不能有枚举(所以你可以将枚举映射到颜色)。我知道我可以通过代码定义颜色,然后有一个插座,但问题是我有大量的视图,我需要子类化只是为了改变这样的颜色:

class TestCommonView: CommonView {
@IBOutlet weak var borderView: UIView!
    override func awakeFromNib() {
        super.awakeFromNib()
        borderView.backgroundColor = Colors.fabrica.pastel
    }
} 

有什么想法吗?

【问题讨论】:

  • 写随机字符串对我来说看起来不太好......
  • @SwiftArchitect 看起来很有希望......我必须把它放到一个小项目中并检查它是否通过了酸性测试。我的意思是,一旦我更改枚举定义中的值并再次运行它,新值应该反映在运行时。
  • 我建议以@IBInspectable 为起点,并与@IB_Designable 配合使用以即时显示颜色。您将依靠适配器将 Int 或 String 放入 IB,而您的 Swift Extension 应将其转换为实际颜色。反过来,该颜色可以直接读取并显示在 IB 中。

标签: ios xcode swift


【解决方案1】:

重新考虑这个声明:

我也试过做一个@IBInspectable,但你不能有枚举(所以你可以将一个枚举映射到一种颜色)。

您可以通过这种方式使用Int 桥接@IBInspectable enum:

enum ColorPalette:Int {
    case clear = 0
    case teal = 1
    case plum = 2
    case foam = 3
}
var tincture:ColorPalette = .clear

在代码中,访问self.tincture,也就是您要的enum。 在Interface Builder中,使用tinctureAdapter,它是一个Int,因此实际上是一个枚举类型的@IBInspectable。

// Stored IB property
@available(*, unavailable, message="Use tincture programmatically")
@IBInspectable var tinctureAdapter:Int {
    get {
        return self.tincture.rawValue
    }
    set {
        self.tincture = ColorPalette:Int(rawValue: newValue) ?? .clear
    }
}

将此代码放在UIColor 类扩展中可能很有用。使用桥接方法,您还可以在 IB 中使用 @Donamite plain-English 字符串。


Swift 3 示例

@IBDesignable class ColorSwatchView: UIView {

    enum ColorPalette: String {
        case Thistle    = "thistle"
        case Plum       = "plum"
        case Olive      = "olive"
        case Iris       = "iris"

        case Clear      = "clear"
    }

    let namedColors = [
        "thistle": UIColor(red: 216/255, green: 191/255, blue: 216/255, alpha: 1),
        "plum"   : UIColor(red: 221/255, green: 160/255, blue: 221/255, alpha: 1),
        "olive"  : UIColor(red: 128/255, green: 128/255, blue: 0/255, alpha: 1),
        "iris"   : UIColor(red: 3/255, green: 180/255, blue: 200/255, alpha: 1)
    ]

    var tincture:ColorPalette = .Clear

    // Stored IB property
    @available(*, unavailable, message: "Use tincture programmatically")
    @IBInspectable var tinctureName: String? {
        willSet {
            if let color = ColorPalette(rawValue: newValue?.lowercased() ?? "") {
                tincture = color
            }
        }
    }
}

界面构建器

让您的自定义视图成为ColorSwatchView的子视图。

以编程方式

override func draw(_ rect: CGRect) {
    let ctx = UIGraphicsGetCurrentContext()
    ctx?.saveGState()
    let uiColor = namedColors[tincture.rawValue] ?? UIColor.clear
    ctx?.setFillColor(uiColor.cgColor)
    ctx?.fill(bounds)
    ctx?.restoreGState()
}

► 在GitHub 上查找此解决方案,在Swift Recipes 上查找更多详细信息。

【讨论】:

  • 我认为这是一个正确的答案。我个人在我的项目中做过类似的事情
  • 在 Apple 提供支持之前,这是我们拥有的最好的。我很惊讶 Color 和 enum 没有添加到 Xcode 7 中,除了 Swift 2.0
猜你喜欢
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
相关资源
最近更新 更多