74

我正在尝试通过 IB 设置视图的图层属性。除边框颜色(属性layer.borderColor)外,一切正常:

在此处输入图像描述

我记得一年前遇到了这个问题,我最终以编程方式解决了这个问题。而且,我仍然可以通过编程方式执行此操作,但我很好奇为什么该layer.borderColor属性从不通过界面生成器工作。我不想 import QuartzCore,然后仅仅因为这个而编写额外的代码行,这似乎是一种矫枉过正。

4

16 回答 16

82

可以这样做,但这不是内置功能。这是因为ColorUser Defined Runtime Attributes 面板中的类型创建了一个UIColor,但layer.borderColor拥有一个CGColorRef类型。不幸的是,没有办法CGColorRef在 Interface Builder 中分配类型。

但是,这可以通过代理属性实现。有关此问题的可能解决方案,请参阅Peter DeWeese 对不同问题的回答。他的回答定义了一个类别,允许通过 Interface Builder 设置代理颜色。

于 2013-02-21T19:16:24.350 回答
49

您必须为 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 中你可以像这样使用它:

在此处输入图像描述

一旦你选择了某事,它就会自动添加到你的运行时属性中:

于 2015-01-16T14:56:06.647 回答
26

复制并粘贴此类:

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 类。

之后,检查您的属性检查器:

带有新 IBInspectable 选项的属性检查器

不再需要弄乱用户定义的运行时属性。您的更改也将显示在画布上!

于 2016-08-20T15:44:12.297 回答
19

将 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
    }
}
于 2015-05-18T19:43:31.753 回答
11

使用 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
        }
    }
}
于 2016-02-16T17:32:05.397 回答
5

这是克服这个问题的快速方法。类别...

@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 中,您没有设置值 on layer.borderColor,而只是设置 on borderColor

于 2013-11-16T22:21:16.537 回答
5

在 Swift 中,您可以扩展UIButton该类并添加一个@IBInspectable使您能够从情节提要中选择一种颜色并设置它的颜色(宽度为 1,可以更改)。在视图控制器的末尾添加:

extension UIButton{
    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(CGColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.CGColor
            layer.borderWidth = 1
        }
    }
}
于 2016-01-22T22:56:15.860 回答
4

为了使 CALayer KVC 兼容属性borderColorFromUIColor,只需实现

layer.borderColorFromUIColor=[UIColor red];

此链接有遮阳篷

于 2014-11-17T08:33:58.457 回答
2

斯威夫特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)
   }
}
于 2018-11-16T04:03:10.557 回答
2

我遇到了同样的问题,我通过创建一个自定义按钮类来解决它:

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”。

简单又好用。:)

于 2016-07-28T03:45:30.043 回答
1

borderColorborderWidth除非图层的属性设置为大于 0的值,否则将不起作用。

斯威夫特 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.
于 2017-02-06T11:06:19.180 回答
0

我认为这可能是因为您将 maskToBounds 设置为 YES。我不认为边界是在图层的边界内绘制的,所以它不会被绘制,因为你将所有东西都隐藏在它的边界之外。

于 2013-02-10T08:32:04.333 回答
0

在用户定义的运行时属性中试试这个:

  1. 关键路径:layer.borderUIColor
  2. 类型:Color
  3. 价值:--you prefered color--
于 2021-02-08T10:48:10.280 回答
0

您可以使用 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)
    }
于 2018-10-25T07:13:24.220 回答
0

您可以在 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
    }
}
于 2017-09-14T09:33:37.670 回答
0

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
    }
}
}
于 2020-07-15T05:49:22.447 回答