wake-up-neo.net

Die Umrandungsfarbe von UIView im Interface Builder funktioniert nicht?

Ich versuche, die Layer-Eigenschaften einer Ansicht über IB einzurichten. Alles funktioniert außer der Farbe des Rahmens (Eigenschaft layer.borderColor):

enter image description here

Ich erinnere mich, dass ich vor einem Jahr auf dieses Problem gestoßen bin und es am Ende programmatisch gemacht habe. Und ich kann das zwar programmgesteuert machen, aber ich bin neugierig, warum die layer.borderColor-Eigenschaft niemals über den Interface Builder funktioniert. Ich möchte QuartzCore nicht importieren und schreibe aus diesem Grund eine zusätzliche Codezeile, die wie ein Overkill wirkt. 

60
0xSina

Dies ist möglich, aber es ist keine integrierte Funktion. Dies liegt daran, dass der Typ Color im Bedienfeld Benutzerdefinierte Laufzeitattribute einen UIColor erstellt, aber layer.borderColor einen CGColorRef-Typ enthält. Leider kann im Interface Builder kein CGColorRef-Typ zugewiesen werden.

Dies ist jedoch über eine Proxy-Eigenschaft möglich. Siehe Peter DeWeeses Antwort auf eine andere Frage, um eine mögliche Lösung für dieses Problem zu finden. Seine Antwort definiert eine Kategorie, in der eine Proxy-Farbe über den Interface Builder festgelegt werden kann.

73
mopsled

Sie müssen eine Kategorie für CALayer erstellen:

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

Und dann in Benutzerdefinierte Laufzeitattribute Sie können es wie in der Abbildung unten verwenden:

enter image description here

Für Swift ist es viel einfacher:

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

Dann können Sie es in Xcode folgendermaßen verwenden:

enter image description here

Sobald Sie sich für etw entschieden haben, wird es automatisch zu Ihren Laufzeitattributen hinzugefügt :

Meine zwei Cent für die Portierung von Bartłomiej Semańczyks Antwort auf Swift:

Erstellen Sie eine Erweiterung für CALayer in Ihrem View-Controller:

import UIKit

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

    func setBorderUIColor(color: UIColor) {
        borderColor = color.CGColor
    }
}
18
Eduardo

Kopieren Sie diese Klasse und fügen Sie sie ein:

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

Wechseln Sie nun im Interface Builder zum Identitätsinspektor und legen Sie Ihre Ansicht als CustomView-Klasse fest.

Überprüfen Sie anschließend Ihren Attribut-Inspektor:

 Attributes inspector with the new IBInspectable options

Sie müssen sich nicht mehr mit benutzerdefinierten Laufzeitattributen herumschlagen. Und Ihre Änderungen werden auch auf der Leinwand angezeigt!

17
etayluz

Verwenden Sie IBDesignable anstelle von Laufzeitattributen. Dies ist klarer.

Fügen Sie diesen Code in eine beliebige Klasse ein und bearbeiten Sie die Eigenschaften direkt im Storyboard.

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
        }
    }
}
9
Fede Henze

Hier ist ein schneller Weg, um dies zu überwinden. Kategorien...

@interface UIView (IBAppearance)

@property (nonatomic, strong) UIColor *borderColor;

@end

Sie müssen es nicht speichern, es ist nur Nizza, so dass Sie später abfragen können. Das Wichtigste ist, den Wert zu übernehmen und die CGColor des UIColors der Ebene zuzuweisen.

#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

Natürlich setzen Sie im Interface Builder den Wert nicht auf layer.borderColor, sondern nur auf borderColor.

5
bainfu

In Swift können Sie die UIButton-Klasse erweitern und einen @IBInspectable hinzufügen, mit dem Sie eine Farbe aus dem Storyboard auswählen und deren Farbe festlegen können (mit der Breite 1, die geändert werden kann). _ Fügen Sie diese am Ende Ihres View-Controllers hinzu :

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

Um CALayer KVC-kompatibel für die Eigenschaft borderColorFromUIColor zu machen, implementieren Sie einfach das 

layer.borderColorFromUIColor=[UIColor red];

Diesen Link haben awnser

3
Mohit

Ich habe das gleiche Problem kennengelernt und bin damit umgegangen, indem ich eine benutzerdefinierte Button-Klasse erstellt habe:

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
}

}

Ändern Sie dann in IB den Typ von "UIButton" in "UIButtonWithRoundBorder".

Einfach und praktisch auch. :)

2
RainCast

Swift4 

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)
   }
}
0
Z King

Sie können einen Wert für den Schlüssel "borderColor" in der XIB festlegen und verwenden:

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

borderColor funktioniert nicht, WENN die borderWidth-Eigenschaft des Layers auf einen Wert größer als 0 gesetzt ist.

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.
0
Malloc

Sie können den Rahmen mit 2 Methoden anpassen .. _. Klicken Sie einfach auf das Objekt, gehen Sie zum Identitätsinspektor und legen Sie die Attribute fest.

 enter image description here

Der zweite ist dies. Erstellen Sie ein IBOutlet des erforderlichen Objekts und setzen Sie diesen Code in die Ansicht, dass er geladen wurde.

@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)
    }
0
akbar khan

Ich denke, das kann daran liegen, dass Sie maskenToBounds auf YES gesetzt haben. Ich denke nicht, dass die Grenze innerhalb der Grenzen der Ebene gezeichnet wird, also wird sie nicht gezeichnet, da Sie alles außerhalb der Grenzen verbergen. 

0
Chris C