I think it may be because you have masksToBounds set to YES. I don't think the border is drawn within the bounds of the layer, so it won't be drawn since you're hiding everything outside of its bounds.
It's possible to do this, but it's not a built-in feature. This is because the Color type in the User Defined Runtime Attributes panel creates a UIColor, but layer.borderColor holds a CGColorRef type. Unfortunately, there's no way to assign a CGColorRef type in Interface Builder.
However, this is possible through a proxy property. See Peter DeWeese's answer to a different question for a possible solution to this problem. His answer defines a category that allows a proxy color to be set through Interface Builder.
You don't have to store it, it's just nice so you can query later. The important thing is taking the value and assigning the UIColor's CGColor to the layer.
In Swift, you can extend the UIButton class and add an @IBInspectable that will enable you to select a color from storyboard and set it's color (with width of 1 which can be changed).
Add this at the end of your view controller:
extension UIButton{
@IBInspectable var borderColor: UIColor? {
get {
return UIColor(CGColor: layer.borderColor!)
}
set {
layer.borderColor = newValue?.CGColor
layer.borderWidth = 1
}
}
}
borderColor will not work UNLESS the borderWidth property of the layer is set to a value greater than 0.
Swift 3:
button.layer.borderColor = UIColor.white.cgColor
button.layer.borderWidth = 1.0 // Default value is 0, that's why omitting this line will not make the border color show.
extension CALayer {
open override func setValue(_ value: Any?, forKey key: String) {
/// If key is borderColor, and the value is the type of a UIColor.
if key == "borderColor" , let color = value as? UIColor {
/// After converting UIColor to CGColor, call the system method.
return super.setValue(color.cgColor, forKey: key)
}
super.setValue(value, forKey: key)
}
}