Цвет границы UIView в Interface builder не работает?


Я пытаюсь настроить свойства слоя представления через IB. Все работает, кроме цвета границы (свойство layer.borderColor):

Я помню, как столкнулся с этой проблемой год назад, и я закончил тем, что сделал это программно. И все же, я могу сделать это программно, но мне любопытно, почему layer.borderColorсвойство никогда не работает через interface builder. Я не хочу импортировать QuartzCore, а затем написать дополнительную строку кода только из-за этого, кажется, перебор.

12 58

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

а потом в пользовательские атрибуты времени выполнения вы можете использовать его как на рисунке ниже:

enter image description here

на Свифт это гораздо проще:

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

затем в Xcode вы можете использовать его как это:

enter image description here

после выбора 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.

после этого проверьте свой инспектор атрибутов:

Attributes inspector with the new IBInspectable options

больше не нужно возиться с пользовательскими атрибутами времени выполнения. И ваши изменения будут отображаться на холсте!

использовать 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];

эта ссылка есть awnser

Я встретил ту же проблему, я работал вокруг него, создавая пользовательский класс кнопки:

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