![](/img/trans.png)
[英]Why doesn't UITableViewCell background color work (set in interface builder)?
[英]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 類。
之后,檢查您的屬性檢查器:
不再需要弄亂用戶定義的運行時屬性。 您的更改也將顯示在畫布上!
將 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
}
}
}
我遇到了同樣的問題,我通過創建一個自定義按鈕類來解決它:
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
}
}
}
在用戶定義的運行時屬性中試試這個:
layer.borderUIColor
Color
--you prefered color--
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.