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

0xS*_*ina 66 cocoa-touch objective-c uiview ios swift

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

在此输入图像描述

我记得一年前碰到这个问题而且我最终以编程方式进行.而且,我仍然可以通过编程方式执行此操作,但我很好奇为什么该layer.borderColor属性永远不会通过界面构建​​器工作.我不想导入QuartzCore,然后因为这个而编写额外的代码行,看起来像是一种矫枉过正.

mop*_*led 78

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

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


Bar*_*zyk 48

您必须为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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

对于Swift来说,它更简单:

@IBInspectable var borderColor: UIColor? {
    didSet {
        layer.borderColor = borderColor?.CGColor
        layer.borderWidth = 1
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

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


eta*_*luz 22

复制并粘贴此类:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在Interface Builder中,转到Identity检查器并将视图设置为CustomView类.

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

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

无需再使用用户定义的运行时属性.您的更改也将显示在画布上!


小智 19

移植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
    }
}
Run Code Online (Sandbox Code Playgroud)


Fed*_*deH 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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

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

@interface UIView (IBAppearance)

@property (nonatomic, strong) UIColor *borderColor;

@end
Run Code Online (Sandbox Code Playgroud)

你不必存储它,它很好,所以你可以稍后查询.重要的是获取值并将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
Run Code Online (Sandbox Code Playgroud)

当然,在Interface Builder中,您不是设置值layer.borderColor,而是仅设置值borderColor.


Hus*_*inB 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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)