UIView在界面構建器中的邊框顏色不起作用?

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


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建立一個視圖的圖層屬性。除了邊框的顏色(屬性層。邊框顏色),其他的都可以:

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.

我記得一年前遇到過這個問題,最后我以編程的方式解決了這個問題。盡管如此,我還是可以用編程的方式來做,但是我很好奇為什么這個層。邊界屬性從來不會通過接口構建器工作。我不想導入QuartzCore,然后僅僅因為這個而編寫額外的代碼行,這似乎有點過頭了。

12 个解决方案

#1


71  

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

這樣做是有可能的,但它不是內置的功能。這是因為用戶定義的運行時屬性面板中的顏色類型創建一個UIColor,但層。邊界顏色保持CGColorRef類型。不幸的是,在接口構建器中沒有辦法分配CGColorRef類型。

However, this is possible through a proxy property. See Peter DeWeese's answer to 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對另一個問題的回答,找到解決這個問題的可能方法。他的回答定義了一個類別,允許通過接口構建器設置代理顏色。

#2


44  

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 attributes You can use it as it is on image below:

然后,在用戶定義的運行時屬性中,可以使用如下圖所示的屬性:

enter image description here

For Swift it is much more simple:

對於斯威夫特來說,事情要簡單得多:

@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:

一旦你選擇某物,它會自動添加到你的運行時屬性:

#3


16  

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

我的兩個美分移植Bartłomiej Semańczyk迅速的回答:

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

#4


13  

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 inspector,並將視圖設置為CustomView類。

After that, check out your Attributes Inspector:

之后,請檢查您的屬性檢查器:

Attributes inspector with the new IBInspectable options

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

不再需要使用用戶定義的運行時屬性。您的更改也將顯示在畫布上!

#5


7  

Use IBDesignable instead of Runtime Attributes it is more clear.

使用IBDesignable而不是Runtime屬性更加清晰。

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

#6


5  

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.

當然,在接口構建器中,不是在層上設置值。邊色,只是邊色。

#7


4  

In Swift, you can extend the UIButton class and add an @IBInspectable that 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,它將使您能夠從storyboard中選擇一個顏色並設置它的顏色(寬度為1,可以更改)。在視圖控制器的末尾添加這個:

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

#8


3  

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

為了使CALayer kvc兼容屬性borderColorFromUIColor,只需實現

layer.borderColorFromUIColor=[UIColor red];

This link have awnser

這個鏈接有芒

#9


2  

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. :)

簡單和方便。:)

#10


0  

I think it may be because you have masksToBounds set to YES. I don't think the border is drawn within the bounds of the layer, so it won't be drawn since you're hiding everything outside of its bounds.

我想可能是因為你的面具被設置為YES。我不認為邊界是在層的邊界內繪制的,所以它不會被繪制,因為你把所有東西都隱藏在它的邊界之外。

#11


0  

borderColor will not work UNLESS the borderWidth property of the layer is set to a value greater than 0.

除非將層的邊界寬度屬性設置為大於0的值,否則邊界顏色將不起作用。

Swift 3:

斯威夫特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.

#12


0  

You can set a value for the "borderColor" key in the XIB and use:

您可以在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
    }
}

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2013/02/09/370351d58dbb76fc7ecf4cd004947b21.html



 
  © 2014-2022 ITdaan.com 联系我们: