簡體   English   中英

界面生成器中 UIView 的邊框顏色不起作用?

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

我正在嘗試通過 IB 設置視圖的圖層屬性。 除了邊框的顏色(屬性layer.borderColor )之外,一切都有效:

在此處輸入圖像描述

我記得一年前遇到了這個問題,我最終以編程方式解決了這個問題。 而且,我仍然可以通過編程方式執行此操作,但我很好奇為什么layer.borderColor屬性從不通過界面生成器工作。 我不想導入QuartzCore ,然后僅僅因為這個而編寫額外的代碼行,這似乎是一種矯枉過正。

可以這樣做,但這不是內置功能。 這是因為 User Defined Runtime Attributes 面板中的Color類型創建了一個UIColor ,但layer.borderColor擁有一個CGColorRef類型。 不幸的是,沒有辦法在 Interface Builder 中分配CGColorRef類型。

但是,這可以通過代理屬性實現。 有關此問題的可能解決方案,請參閱Peter DeWeese 對不同問題的回答 他的回答定義了一個類別,允許通過 Interface Builder 設置代理顏色。

您必須為 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 中你可以像這樣使用它:

在此處輸入圖像描述

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

復制並粘貼此類:

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 選項的屬性檢查器

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

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

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

這是克服這個問題的快速方法。 類別...

@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上設置值。

在 Swift 中,您可以擴展UIButton類並添加一個@IBInspectable ,使您能夠從情節提要中選擇一種顏色並設置它的顏色(寬度為 1,可以更改)。 在視圖控制器的末尾添加:

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

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

layer.borderColorFromUIColor=[UIColor red];

此鏈接有遮陽篷

我遇到了同樣的問題,我通過創建一個自定義按鈕類來解決它:

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

簡單又好用。 :)

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

除非圖層的borderWidth屬性設置為大於0的值,否則borderColor將不起作用。

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

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

我認為這可能是因為您將 maskToBounds 設置為 YES。 我不認為邊界是在圖層的邊界內繪制的,所以它不會被繪制,因為你將所有東西都隱藏在它的邊界之外。

您可以使用 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)
    }

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

用戶定義的運行時屬性中試試這個:

  1. 關鍵路徑: layer.borderUIColor
  2. 類型: Color
  3. 值: --you prefered color--

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM