![](/img/trans.png)
[英]Why doesn't UITableViewCell background color work (set in interface builder)?
[英]UIView's border color in Interface builder doesn't work?
我正在尝试通过 IB 设置视图的图层属性。 除了边框的颜色(属性layer.borderColor
)之外,一切都有效:
我记得一年前遇到了这个问题,我最终以编程方式解决了这个问题。 而且,我仍然可以通过编程方式执行此操作,但我很好奇为什么layer.borderColor
属性从不通过界面生成器工作。 我不想导入QuartzCore
,然后仅仅因为这个而编写额外的代码行,这似乎是一种矫枉过正。
可以这样做,但这不是内置功能。 这是因为 User Defined Runtime Attributes 面板中的Color
类型创建了一个UIColor
,但layer.borderColor
拥有一个CGColorRef
类型。 不幸的是,没有办法在 Interface Builder 中分配CGColorRef
类型。
但是,这可以通过代理属性实现。 有关此问题的可能解决方案,请参阅Peter DeWeese 对不同问题的回答。 他的回答定义了一个类别,允许通过 Interface Builder 设置代理颜色。
您必须为 CALayer 创建类别:
CALayer+UIColor.h
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
@interface CALayer(UIColor)
// This assigns a CGColor to borderColor.
@property(nonatomic, assign) UIColor* borderUIColor;
@end
CALayer+UIColor.m
#import "CALayer+UIColor.h"
@implementation CALayer(UIColor)
- (void)setBorderUIColor:(UIColor*)color {
self.borderColor = color.CGColor;
}
- (UIColor*)borderUIColor {
return [UIColor colorWithCGColor:self.borderColor];
}
@end
然后在用户定义的运行时属性中,您可以使用它,如下图所示:
对于Swift ,它要简单得多:
import QuartzCore
extension CALayer {
@IBInspectable var borderUIColor: UIColor? {
get {
guard let borderColor = borderColor else { return nil }
return UIColor(cgColor: borderColor)
}
set {
borderColor = newValue?.cgColor
}
}
}
然后在 Xcode 中你可以像这样使用它:
一旦你选择了某事,它就会自动添加到你的运行时属性中:
复制并粘贴此类:
import UIKit
@IBDesignable class BorderView : UIView {
@IBInspectable var borderColor: UIColor = .clear {
didSet {
layer.borderColor = borderColor.cgColor
}
}
@IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
@IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
}
}
}
现在在 Interface Builder 中,转到 Identity 检查器并将您的视图设置为 CustomView 类。
之后,检查您的属性检查器:
不再需要弄乱用户定义的运行时属性。 您的更改也将显示在画布上!
将 Bartłomiej Semańczyk 对 Swift 的回答移植到我的两分钱:
在视图控制器中为 CALayer 创建一个扩展:
import UIKit
extension CALayer {
func borderUIColor() -> UIColor? {
return borderColor != nil ? UIColor(CGColor: borderColor!) : nil
}
func setBorderUIColor(color: UIColor) {
borderColor = color.CGColor
}
}
使用 IBDesignable 而不是运行时属性更清楚。
将此代码放在任何类中并直接在情节提要上编辑属性。
import UIKit
@IBDesignable extension UIView {
@IBInspectable var borderColor:UIColor? {
set {
layer.borderColor = newValue!.CGColor
}
get {
if let color = layer.borderColor {
return UIColor(CGColor:color)
}
else {
return nil
}
}
}
@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
}
}
}
这是克服这个问题的快速方法。 类别...
@interface UIView (IBAppearance)
@property (nonatomic, strong) UIColor *borderColor;
@end
您不必存储它,它很好,因此您可以稍后查询。 重要的是取值并将 UIColor 的 CGColor 分配给图层。
#import <objc/runtime.h>
#define BORDER_COLOR_KEYPATH @"borderColor"
@implementation UIView (IBAppearance)
- (void)setBorderColor:(UIColor *)borderColor {
UIColor *bc = objc_getAssociatedObject(self, BORDER_COLOR_KEYPATH);
if(bc == borderColor) return;
else {
objc_setAssociatedObject(self, BORDER_COLOR_KEYPATH, borderColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
self.layer.borderColor = [borderColor CGColor];
}
}
- (UIColor *)borderColor {
return objc_getAssociatedObject(self, BORDER_COLOR_KEYPATH);
}
@end
当然,在 Interface Builder 中,您不会在layer.borderColor
上设置值,而只是在borderColor
上设置值。
在 Swift 中,您可以扩展UIButton
类并添加一个@IBInspectable
,使您能够从情节提要中选择一种颜色并设置它的颜色(宽度为 1,可以更改)。 在视图控制器的末尾添加:
extension UIButton{
@IBInspectable var borderColor: UIColor? {
get {
return UIColor(CGColor: layer.borderColor!)
}
set {
layer.borderColor = newValue?.CGColor
layer.borderWidth = 1
}
}
}
我遇到了同样的问题,我通过创建一个自定义按钮类来解决它:
class UIButtonWithRoundBorder: UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.cornerRadius = 6
self.layer.borderWidth = 1
self.layer.borderColor = UIColor.whiteColor().CGColor
self.clipsToBounds = true
}
}
然后在 IB 中,将类型从“UIButton”更改为“UIButtonWithRoundBorder”。
简单又好用。 :)
斯威夫特4
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)
}
}
除非图层的borderWidth
属性设置为大于0的值,否则borderColor
将不起作用。
斯威夫特 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.
您可以在 XIB 中为“borderColor”键设置一个值并使用:
extension UIView {
open override func setValue(_ value: Any?, forKey key: String) {
guard key == "borderColor", let color = value as? UIColor else {
super.setValue(value, forKey: key)
return
}
layer.borderColor = color.cgColor
}
}
我认为这可能是因为您将 maskToBounds 设置为 YES。 我不认为边界是在图层的边界内绘制的,所以它不会被绘制,因为你将所有东西都隐藏在它的边界之外。
您可以使用 2 种方法自定义边框。 第一个是这个。 只需单击对象转到身份检查器并设置属性。
第二个是这个。 制作所需对象的 IBOutlet 并将此代码放在视图中确实加载了。
@IBOutlet weak var uploadView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
uploadView.layer.cornerRadius = 10
uploadView.layer.borderWidth = 1.0
uploadView.layer.borderColor = #colorLiteral(red: 0.08235294118, green: 0.5058823529, blue: 0.9450980392, alpha: 1)
}
Swift 5.2 - Fede Henze 的回答
@IBDesignable extension UIView {
@IBInspectable var borderColor:UIColor? {
set {
layer.borderColor = newValue!.cgColor
}
get {
if let color = layer.borderColor {
return UIColor(cgColor:color)
}
else {
return nil
}
}
}
@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
}
}
}
在用户定义的运行时属性中试试这个:
layer.borderUIColor
Color
--you prefered color--
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.