Цвет границы UIView в Interface builder не работает?
Я пытаюсь настроить свойства слоя представления через IB. Все работает, кроме цвета границы (свойство layer.borderColor
):
Я помню, как столкнулся с этой проблемой год назад, и я закончил тем, что сделал это программно. И все же, я могу сделать это программно, но мне любопытно, почему layer.borderColor
свойство никогда не работает через interface builder. Я не хочу импортировать QuartzCore
, а затем написать дополнительную строку кода только из-за этого, кажется, перебор.
12 ответов:
Это можно сделать, но это не встроенная функция. Это потому что
Color
введите в пользовательской панели атрибутов выполнения создаетUIColor
, аlayer.borderColor
держитCGColorRef
тип. К сожалению, нет никакого способа назначитьCGColorRef
введите в Interface Builder.однако, это возможно через прокси-собственность. Смотрите Питер 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.м
#import "CALayer+UIColor.h" @implementation CALayer(UIColor) - (void)setBorderUIColor:(UIColor*)color { self.borderColor = color.CGColor; } - (UIColor*)borderUIColor { return [UIColor colorWithCGColor:self.borderColor]; } @end
а потом в пользовательские атрибуты времени выполнения вы можете использовать его как на рисунке ниже:
на Свифт это гораздо проще:
@IBInspectable var borderColor: UIColor? { didSet { layer.borderColor = borderColor?.CGColor layer.borderWidth = 1 } }
затем в Xcode вы можете использовать его как это:
после выбора sth он автоматически добавляется в ваш атрибуты времени выполнения:
мои два цента за перенос ответа Бартломея Семанчика на Swift:
создайте расширение для CALayer в контроллере вида:
import UIKit extension CALayer { func borderUIColor() -> UIColor? { return borderColor != nil ? UIColor(CGColor: borderColor!) : nil } func setBorderUIColor(color: UIColor) { borderColor = color.CGColor } }
скопируйте и вставьте этот класс:
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.
после этого проверьте свой инспектор атрибутов:
больше не нужно возиться с пользовательскими атрибутами времени выполнения. И ваши изменения будут отображаться на холсте!
использовать 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
вы не должны хранить его, это просто приятно, так что вы можете запрос позже. Важно принять значение и присвоить cgcolor UIColor слою.
#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
конечно, в Построителе интерфейса вы не устанавливаете значение на
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 КВК-совместимый для 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".
простой и удобный тоже. :)
borderColor
СborderWidth
свойству слоя присваивается значение больше 0.Swift 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.
Я думаю, что это может быть потому, что у вас есть masksToBounds установлен в да. Я не думаю, что граница рисуется в пределах слоя, поэтому она не будет нарисована, так как вы скрываете все за его пределами.
вы можете установить значение для ключа "borderColor" в 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 } }