2013-02-09 83 views
51

我想通过IB设置一个视图的图层属性。一切正常,除了边框的颜色(属性layer.borderColor):界面生成器中的UIView边框颜色不起作用?

enter image description here

我记得一年前运行到这个问题,我结束了编程这样做。而且,我仍然可以通过编程来实现,但我很好奇为什么layer.borderColor属性从不通过接口构建器工作。我不想导入QuartzCore,然后为此编写额外的代码行,看起来像是一种矫枉过正的行为。

+1

“写的,只是因为这个代码额外的行,看起来像一个矫枉过正的“ - 你的应用程序必须包含至多10行代码然后(包括C标准头文件):P – 2013-02-09 22:22:38

+0

@ H2CO3大声笑...我只是不喜欢写代码,我不必 – 0xSina 2013-02-09 23:33:26

+0

我过去犯过这个错误..我希望你ou知道它..否则检查从这第一个答案:http://stackoverflow.com/questions/3980251/user-defined-runtime-attributes-in-ib-for-iphone-not-working – chuthan20 2013-02-10 22:20:10

回答

71

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

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

0

我认为这可能是因为您将masksToBounds设置为YES。我不认为边界被绘制在图层的边界内,所以它不会被绘制,因为您将所有内容都隐藏在边界之外。

+0

嗯...不@我的桌面,所以将试验那,但如果我设置masksToBounds为NO,那么我不能有UIImageView圆角/角半径:( – 0xSina 2013-02-10 19:18:20

5

下面是一个快速解决这个问题的方法。分类...

@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

+0

我认为没有必要使用关联的对象,因为可能发生的事情和你的borderColor将与layer.borderColor不同步 刚刚返回[UIColor colorWithCGColor:self.layer.borderColor] – storoj 2013-11-17 00:09:51

+1

您是完全正确的@storoj。这是一种我们用来添加属性并能够使用类别存储它的模式。这里误用了 – bainfu 2014-01-22 21:47:14

3

为了使CALayer的KVC兼容的财产borderColorFromUIColor,简单地实现

layer.borderColorFromUIColor=[UIColor red]; 

This link have awnser

+0

谢谢MOHIT,并感谢你APPLE! – Fattie 2015-08-16 19:23:00

+1

不再使用Swift-4 – itsji10dra 2017-09-27 20:38:17

43

你必须为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。米

#import "CALayer+UIColor.h" 

@implementation CALayer(UIColor) 

- (void)setBorderUIColor:(UIColor*)color { 
    self.borderColor = color.CGColor; 
} 

- (UIColor*)borderUIColor { 
    return [UIColor colorWithCGColor:self.borderColor]; 
} 

@end 

然后在用户定义运行属性您可以使用它,因为它是在图片下:

enter image description here

对于斯威夫特它是更简单:

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

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

enter image description here

一旦选择了某事它会自动添加到您的运行属性

+0

这是最简单的解决方案,也是我实施的解决方案。 nside是你可以忘记它在那里(只有几行!)。 – 2015-07-02 15:51:56

+0

为什么borderUIColor属性是'assign'而不是'strong'?这是一种对象类型,这不会导致问题吗? – 2016-07-04 07:47:13

+0

^因为它不包含该值,它会将其传递。 – tGilani 2017-02-17 04:58:16

16

我的两分钱用于移植巴特洛梅耶Semańczyk的回答让斯威夫特:

创建的CALayer延期在您的视图控制器中:

import UIKit 

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

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

它的工作原理,但添加'导入UIKit'缺少 – seapy 2015-06-28 03:23:06

+0

谢谢爱德华多,这个作品。 – DeyaEldeen 2016-06-15 10:58:50

4

在Swif t,您可以扩展UIButton类并添加一个@IBInspectable,使您可以从故事板中选择一种颜色并将其设置为颜色(宽度为1,可以更改)。 在您的视图控制器的最后补充一点:

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

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

当您将这些应用于多个项目时,这会节省大量头痛。光滑的小珍闻。 – Haligen 2016-07-15 16:47:24

+0

对不起,但这不起作用。我刚刚尝试过。 @IBDesignable不适用于UIView的扩展。 http://stackoverflow.com/questions/29906855/can-you-add-ibdesignable-properties-to-uiview-using-categories-extensions – etayluz 2016-08-20 16:07:41

+0

刚刚尝试过一些使用Swift 3.0的大小写问题。耻辱,我以前不知道这一点。 – 2016-12-28 20:34:37

2

我遇到了同样的问题,我的工作围绕它通过创建一个自定义按钮:

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

简单而方便。 :)

10

复制并粘贴这个类:

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中,去身份检查和设置您的视图作为CustomView类。各地

Attributes inspector with the new IBInspectable options

没有必要惹用户定义的运行属性了:

之后,看看你的属性检查器。而且您的更改也会显示在画布上!

+1

非常好的解决方案,欢呼! – 2016-12-12 13:43:05

0

borderColor将无法​​使用,除非该图层的borderWidth属性设置为大于0的值。

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

你的回答与这个问题无关。海报说,他知道如何以编程方式做到这一点。此外,你可以看到他已经在他的截图中将borderWidth设置为> 1。他问在IB中专门做这件事。 – jungledev 2017-07-21 17:35:05

0

您可以在厦门国际银行的 “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 
    } 
} 
相关问题