74

IBを介してビューのレイヤープロパティを設定しようとしています。layer.borderColor境界線の色(プロパティ)を除いて、すべてが機能します。

ここに画像の説明を入力してください

1年前にこの問題に遭遇したことを覚えており、プログラムで問題を解決することになりました。それでも、これはプログラムで実行できますが、なぜlayer.borderColorプロパティがInterfaceBuilderを介して機能しないのか興味があります。をインポートしたくないQuartzCoreので、これだけの理由で余分なコード行を記述しますが、やり過ぎのようです。

4

16 に答える 16

82

これを行うことは可能ですが、組み込みの機能ではありません。これはColor、[ユーザー定義のランタイム属性]パネルのタイプがを作成しますUIColorlayer.borderColor、タイプを保持しているためCGColorRefです。残念ながら、CGColorRefInterfaceBuilderでタイプを割り当てる方法はありません。

ただし、これはプロキシプロパティを介して可能です。この問題の可能な解決策については、別の質問に対するPeterDeWeeseの回答を参照してください。彼の答えは、InterfaceBuilderを介してプロキシカラーを設定できるカテゴリを定義しています。

于 2013-02-21T19:16:24.350 に答える
49

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では次のように使用できます。

ここに画像の説明を入力してください

sthを選択すると、ランタイム属性に自動的に追加されます。

于 2015-01-16T14:56:06.647 に答える
26

このクラスをコピーして貼り付けます。

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クラスとして設定します。

その後、属性インスペクターを確認してください。

新しいIBInspectableオプションを備えた属性インスペクター

ユーザー定義のランタイム属性をいじくり回す必要はもうありません。また、変更はキャンバスにも表示されます。

于 2016-08-20T15:44:12.297 に答える
19

BartłomiejSemańczykのSwiftへの回答を移植するための私の2セント:

ビューコントローラでCALayerの拡張機能を作成します。

import UIKit

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

    func setBorderUIColor(color: UIColor) {
        borderColor = color.CGColor
    }
}
于 2015-05-18T19:43:31.753 に答える
11

ランタイム属性の代わりに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
        }
    }
}
于 2016-02-16T17:32:05.397 に答える
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

于 2013-11-16T22:21:16.537 に答える
5

Swiftでは、UIButtonクラスを拡張し@IBInspectable、ストーリーボードから色を選択してその色を設定できるようにするを追加できます(幅1は変更可能)。ビューコントローラの最後にこれを追加します。

extension UIButton{
    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(CGColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.CGColor
            layer.borderWidth = 1
        }
    }
}
于 2016-01-22T22:56:15.860 に答える
4

プロパティborderColorFromUIColorに対してCALayerKVCに準拠させるには、単純に

layer.borderColorFromUIColor=[UIColor red];

このリンクにはawnserがあります

于 2014-11-17T08:33:58.457 に答える
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」に変更します。

シンプルで便利です。:)

于 2016-07-28T03:45:30.043 に答える
2

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)
   }
}
于 2018-11-16T04:03:10.557 に答える
1

borderColorborderWidthレイヤーのプロパティが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.
于 2017-02-06T11:06:19.180 に答える
0

masksToBoundsがYESに設定されていることが原因である可能性があります。境界線はレイヤーの境界内に描画されるとは思わないので、境界の外側にすべてを非表示にしているため、境界線は描画されません。

于 2013-02-10T08:32:04.333 に答える
0

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
    }
}
于 2017-09-14T09:33:37.670 に答える
0

2つの方法で境界線をカスタマイズできます。最初はこれです。オブジェクトをクリックするだけで、IDインスペクターに移動し、属性を設定します。

ここに画像の説明を入力してください

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)
    }
于 2018-10-25T07:13:24.220 に答える
0

Swift5.2-FedeHenzeの回答

@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
    }
}
}
于 2020-07-15T05:49:22.447 に答える
0

ユーザー定義のランタイム属性でこれを試してください:

  1. キーパス:layer.borderUIColor
  2. タイプ:Color
  3. 価値:--you prefered color--
于 2021-02-08T10:48:10.280 に答える