界面生成器中UIView的边框颜色不起作用?

时间:2013-02-09 22:19:28

标签: ios objective-c swift cocoa-touch uiview

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

enter image description here

我记得一年前遇到过这个问题,我最终以编程方式进行。而且,我仍然可以通过编程方式执行此操作,但我很好奇为什么layer.borderColor属性永远不会通过接口构建器工作。我不想导入QuartzCore,然后因此而编写额外的代码行,似乎有点矫枉过正。

16 个答案:

答案 0 :(得分:76)

可以这样做,但它不是内置功能。这是因为“用户定义的运行时属性”面板中的Color类型会创建UIColor,但layer.borderColor会保留CGColorRef类型。不幸的是,无法在Interface Builder中分配CGColorRef类型。

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

答案 1 :(得分:47)

您必须为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

然后在用户定义的运行时属性中,您可以在下面的图片中使用它:

enter image description here

对于 Swift ,它更简单:

@IBInspectable var borderColor: UIColor? {
    didSet {
        layer.borderColor = borderColor?.CGColor
        layer.borderWidth = 1
    }
}

然后在Xcode中你可以像这样使用它:

enter image description here

选择某项后,它会自动添加到运行时属性

答案 2 :(得分:18)

移植BartłomiejSemańczyk对Swift的回答是我的两分钱:

在视图控制器中为CALayer创建扩展程序:

import UIKit

extension CALayer {
    func borderUIColor() -> UIColor? {
        return borderColor != nil ? UIColor(CGColor: borderColor!) : nil
    }

    func setBorderUIColor(color: UIColor) {
        borderColor = color.CGColor
    }
}

答案 3 :(得分:18)

复制并粘贴此课程:

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

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

Attributes inspector with the new IBInspectable options

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

答案 4 :(得分:9)

使用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
        }
    }
}

答案 5 :(得分: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中,您没有在layer.borderColor上设置值,而只是在borderColor上设置。

答案 6 :(得分:4)

在Swift中,您可以扩展$2=5类并添加UIButton,以便您从故事板中选择颜色并设置其颜色(宽度为1,可以是改变)。 在视图控制器的末尾添加它:

@IBInspectable

答案 7 :(得分:3)

为了使属性borderColorFromUIColor符合CALayer KVC,只需实现

layer.borderColorFromUIColor=[UIColor red];

This link have awnser

答案 8 :(得分: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中,从&#34; UIButton&#34;更改类型。 to&#34; UIButtonWithRoundBorder&#34;。

简单而且方便。 :)

答案 9 :(得分:0)

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

答案 10 :(得分:0)

除非图层的borderColor属性设置为值大于0 ,否则

borderWidth将无效。

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.

答案 11 :(得分:0)

您可以为&#34; borderColor&#34;设置一个值。键入XIB并使用:

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
    }
}

答案 12 :(得分:0)

您可以使用2种方法自定义边框。 第一个是这个。只需单击该对象,然后转到身份检查器并设置属性。

enter image description here

第二个是这个。创建所需对象的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)
    }

答案 13 :(得分:0)

swift4

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)
   }
}

答案 14 :(得分: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
    }
}
}

答案 15 :(得分:0)

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

  1. 密钥路径:layer.borderUIColor
  2. 输入:Color
  3. 值:--you prefered color--