将自定义边框颜色 Alpha 添加到属性检查器

Adding Custom Border Color Alpha to Attribute Inspector

我有一个分为两部分的问题。首先,我想添加边框颜色 alpha 作为自定义属性,如图所示。

但我注意到的第一件事是要设置边框颜色,必须使用 CGColor 而不是 UIColor 并且 CGColor.alpha 是只读的。

所以我尝试使用类似的东西,但它并没有真正起作用。

@IBInspectable var borderAlpha: CGFloat {
    set {
        let borderCGColor = layer.borderColor
        var color = UIColor(cgColor: borderCGColor!)

        if (newValue < 0) {
            color = color.withAlphaComponent(0)
            layer.borderColor = color.cgColor
        } else if (newValue > 1) {
            color = color.withAlphaComponent(1)
            layer.borderColor = color.cgColor
        } else {
            color = color.withAlphaComponent(newValue)
            layer.borderColor = color.cgColor
        }
    }
    get {
        return layer.borderColor!.alpha
    }
}

我确实在用户定义的运行时属性中得到了这个,但它没有生效。

我的猜测是因为所有用户定义的运行时属性都是在实际使用的函数之后调用的,而我的不是真正的函数,更多的是自定义函数来实现我想要的。 我也知道您可以 select 带有颜色 select 的 alpha 或者,但是对于我正在做的事情,如果它们是分开的就更好了。

最后,作为第二个问题,在增加或减少值的箭头上,它跳了一个,但是在Xcode的alpha box上它只跳了0.05并且不能低于0或高于 1。如何将此类功能添加到我的用户定义的运行时属性中?

编辑 这是我为 UIView 提供的完整扩展代码,它适用于除边框 alpha 之外的所有内容。

import UIKit

@IBDesignable extension UIView {

@IBInspectable var borderColor: UIColor? {
    set {
        layer.borderColor = newValue!.cgColor
    }
    get {
        if let color = self.layer.borderColor {
            return UIColor(cgColor: color)
        } else {
            return nil
        }
    }
}

@IBInspectable var borderAlpha: CGFloat {
    set {
        let borderCGColor = layer.borderColor
        var color = UIColor(cgColor: borderCGColor!)

        if (newValue < 0) {
            color = color.withAlphaComponent(0)
            layer.borderColor = color.cgColor
        } else if (newValue > 1) {
            color = color.withAlphaComponent(1)
            layer.borderColor = color.cgColor
        } else {
            color = color.withAlphaComponent(newValue)
            layer.borderColor = color.cgColor
        }
    }
    get {
        return layer.borderColor!.alpha
    }
}

@IBInspectable var borderWidth: CGFloat {
    set {
        layer.borderWidth = newValue
    }
    get {
        return layer.borderWidth
    }
}

@IBInspectable var cornerRadius: CGFloat {
    set {
        layer.cornerRadius = newValue
        clipsToBounds = newValue > 0
    }
    get {
        return layer.cornerRadius
    }
}

@IBInspectable var shadowColor: UIColor? {
    set {
        layer.shadowColor = newValue!.cgColor
    }
    get {
        if let color = self.layer.shadowColor {
            return UIColor(cgColor: color)
        } else {
            return nil
        }
    }
}

@IBInspectable var shadowOffset: CGSize {
    set {
        layer.shadowOffset = newValue
    }
    get {
        return layer.shadowOffset
    }
}

@IBInspectable var shadowRadius: CGFloat {
    set {
        layer.shadowRadius = newValue
    }
    get {
        return layer.shadowRadius
    }
}

@IBInspectable var shadowOpacity: Float {
    set {
        if (newValue < 0) {
            layer.shadowOpacity = 0
        } else if (newValue > 1) {
            layer.shadowOpacity = 1
        } else {
            layer.shadowOpacity = newValue
        }
    }
    get {
        return layer.shadowOpacity
    }
}
}

我的第一个想法是,您的 borderColorborderAlpha 可能存在根本的不确定性,至于 将首先评估。 没有这一点是已知的或有保证的,所以如果碰巧设置了 borderAlpha 然后 borderColorborderAlpha 将不会神奇地重新计算。实际上,这里的相互依赖引入了一种不确定性,这可能是我们经验差异的原因。因此,将 alpha 设置为颜色的一部分可能会更好。

我们可以猜到这可能是正确的,因为你的 borderAlpha 对我来说很好用:

我们可以猜测,因为它对您不起作用,所以这种差异只是偶然;我很幸运,因为我的 borderAlpha 显然是在我的 borderColor 之后被评估的,但我们大概不能指望这一点。

顺便说一句,我也让你的影子属性起作用了:

您一定已经注意到它们不起作用,对吗?那是因为这一行:

clipsToBounds = newValue > 0

同样,这可以随时出现并将您的 clipsToBounds 设置为 false,从而切断阴影。 (或者也许他们 为你工作的,同样,这只是关于事物评估顺序的运气问题;这里的相互依赖是 clipsToBounds 是在 cornerRadius 中设置但会影响阴影。

简而言之,我认为我们在这里学到的是,您需要保持这些属性彼此正交(独立)。