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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14792238/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 22:14:51  来源:igfitidea点击:

UIView's border color in Interface builder doesn't work?

iosobjective-cswiftcocoa-touchuiview

提问by 0xSina

I am trying to set up a view's layer properties via IB. Everything works except for color of the border (property layer.borderColor):

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

enter image description here

在此处输入图片说明

I remember running into this problem a year ago and I ended up doing it programatically. And still, I can do this programmatically, but I am curious why the layer.borderColorproperty never works via interface builder. I don't want to import QuartzCore, and then write extra line of code just because of this, seems like an overkill.

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

回答by mopsled

It's possible to do this, but it's not a built-in feature. This is because the Colortype in the User Defined Runtime Attributes panel creates a UIColor, but layer.borderColorholds a CGColorReftype. Unfortunately, there's no way to assign a CGColorReftype in Interface Builder.

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

However, this is possible through a proxy property. See Peter DeWeese's answerto 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.

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

回答by Bart?omiej Semańczyk

You have to create Category for CALayer:

您必须为 CALayer 创建类别:

CALayer+UIColor.h

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

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

And then in User Defined Runtime attributesYou can use it as it is on image below:

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

enter image description here

在此处输入图片说明

For Swiftit is much more simple:

对于Swift,它要简单得多:

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

Then in Xcode you can use it like this:

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

enter image description here

在此处输入图片说明

Once you choose sth it is automatically added to your runtime attributes:

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

回答by etayluz

Copy and paste this class:

复制并粘贴此类:

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

Now in Interface Builder, go to the Identity inspector and set your view as a CustomView class.

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

After that, check out your Attributes Inspector:

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

Attributes inspector with the new IBInspectable options

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

No need to mess around with user defined runtime attributes anymore. And your changes will also show up on the canvas!

无需再纠结于用户定义的运行时属性。您的更改也会显示在画布上!

回答by Eduardo

My two cents for porting Bart?omiej Semańczyk's answer to Swift:

我移植 Bart?omiej Semańczyk 对 Swift 的回答的两分钱:

Create an extension for CALayer in your view controller:

在你的视图控制器中为 CALayer 创建一个扩展:

import UIKit

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

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

回答by Fede Henze

Use IBDesignable instead of Runtime Attributes it is more clear.

使用 IBDesignable 而不是 Runtime Attributes 更清晰。

Put this code in any class and edit the properties direct on the storyboard.

将此代码放在任何类中并直接在情节提要上编辑属性。

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

回答by HusseinB

In Swift, you can extend the UIButtonclass and add an @IBInspectablethat 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:

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

extension UIButton{
    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(CGColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.CGColor
            layer.borderWidth = 1
        }
    }
}

回答by bainfu

Here's a quick way to overcome this. Categories...

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

@interface UIView (IBAppearance)

@property (nonatomic, strong) UIColor *borderColor;

@end

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.

您不必存储它,它只是很好,以便您以后可以查询。重要的是取值并将 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

Of course, in the Interface Builder you're not setting the value on layer.borderColor, rather just on borderColor.

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

回答by Mohit

In order to make CALayer KVC-compliant for the property borderColorFromUIColor, simply implement the

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

layer.borderColorFromUIColor=[UIColor red];

This link have awnser

此链接有 awnser

回答by RainCast

I met the same issue, I worked around it by creating a custom button class:

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

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
}

}

Then in IB, change the type from "UIButton" to "UIButtonWithRoundBorder".

然后在 IB 中,将类型从“UIButton”更改为“UIButtonWithRoundBorder”。

Simple and handy too. :)

也简单好用。:)

回答by zheng

swift4

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