Zmień UIButton BorderColor w Storyboard

80

Ustawiłem CornerRadius i BorderWidth dla UIbutton w atrybutach wykonawczych zdefiniowanych przez użytkownika. Bez dodawania layer.borderColor działa dobrze i wyświetla obramowanie w kolorze czarnym. Ale po dodaniu warstwy.borderColor nie działa (nie wyświetla obramowania).

wprowadź opis obrazu tutaj

Mohamed Jaleel Nazir
źródło

Odpowiedzi:

159

Dla Swift:

wprowadź opis obrazu tutaj

Swift 3:

extension UIView {

    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }

    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(cgColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.cgColor
        }
    }
}

Swift 2.2:

extension UIView {

    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }

    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(CGColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.CGColor
        }
    }
}
Mohamed Jaleel Nazir
źródło
witam tworzę klasę CustomeView w celu c, ale nie jest ona wyświetlana w moim storyboardzie. Plz pomóż mi.
Pooja Srivastava
Wielkie dzięki za to! :)
Vijay VS
Dzięki, niesamowite, idealne
Abo3atef,
1
Cudownie, jednak XCode (wersja 8.3.3 (8E3004b)) nie wyświetla wyników w podglądzie, czy to jest właściwe i nie ma możliwości zmiany (z wyjątkiem tworzenia niestandardowego widoku)?
Konstantin Berkov
To najbardziej eleganckie rozwiązanie! Dobra robota!
Zoltan Vinkler
88

Dostałem odpowiedź. Zmień borderColor zamiast layer.borderColor :

Fragment Xcode

i dodaj ten kod w pliku .m:

#import <QuartzCore/QuartzCore.h>
@implementation CALayer (Additions)

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

@end

Zaznacz właściwości w Inspektorze atrybutów

Inspektor atrybutów

Mohamed Jaleel Nazir
źródło
5
@jithin Napisałem to jako rozszerzenie Swift, oto kod: rozszerzenie CALayer {func setBorderColorFromUIColor (color: UIColor) {self.borderColor = color.CGColor}}
Guy
1
sztuczka zadziałała. częściowo. jak, u licha, mam czarne obramowanie, mimo że określiłem kolor czerwony? !!!!!! jakieś pomysły? ktoś?
static0886
@ static0886: To dlatego, że nakładany kolor nie jest ustawiony na obramowaniu. Zgodnie z moim rozumieniem nie możemy ustawić koloru obramowania ze scenorysu, ponieważ ta właściwość nie zostanie odzwierciedlona w komponencie UIComponent w czasie wykonywania. Domyślnie jest to kolor czarny. Jeśli chcesz spróbować, usuwając właściwość koloru z atrybutów.
Javeed
Dla szybkiego możesz ustawić to jako: self.button.layer.borderColor = <UIColor.CGColor>
Sam
Ta warstwa layer.borderColorFromUIColor działała dla mnie w storyboardzie. Dziękuję Ci.
Ramakrishna,
50

Swift 4, Xcode 9.2 - Użyj IBDesignablei IBInspectabledo tworzenia niestandardowych formantów i podglądu projektu na żywo w programie Interface Builder.

Oto przykładowy kod w Swift, umieszczony tuż pod UIKitplikiem w ViewController.swift:

@IBDesignable extension UIButton {

    @IBInspectable var borderWidth: CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
        }
        get {
            return layer.cornerRadius
        }
    }

    @IBInspectable var borderColor: UIColor? {
        set {
            guard let uiColor = newValue else { return }
            layer.borderColor = uiColor.cgColor
        }
        get {
            guard let color = layer.borderColor else { return nil }
            return UIColor(cgColor: color)
        }
    }
}

Jeśli przejdziesz do atrybutów widoku, które można przeglądać, powinieneś wizualnie znaleźć te właściwości, edytuj właściwości:

wprowadź opis obrazu tutaj

Zmiany są również odzwierciedlane w atrybutach czasu wykonywania zdefiniowanych przez użytkownika:

wprowadź opis obrazu tutaj

Uruchom w czasie kompilacji i Voila! zobaczysz swój wyraźny zaokrąglony przycisk z obramowaniem.

wprowadź opis obrazu tutaj

Wady Bulaquena
źródło
Pomogło mi to osiągnąć to w scenorysie. Twoja odpowiedź jest bardzo jasna do wdrożenia.
R. Mohan,
To najdokładniejsza odpowiedź na to pytanie z jasno wyjaśnionym przykładem.
SeaWarrior404
Jeśli możesz dodać do celu C, zostanie to docenione.
Mihir Oza
9

Wyjaśnienie, być może zagubione w niektórych innych odpowiedziach tutaj:

Powodem, dla którego ta właściwość nie jest ustawiana, jest konieczność layer.borderColorpodania wartości typu CGColor.

Ale tylko UIColortypy można ustawić za pomocą zdefiniowanych przez użytkownika atrybutów wykonawczych programu Interface Builder!

Dlatego należy ustawić UIColor na właściwość proxy za pośrednictwem Interface Builder, a następnie przechwycić to wywołanie, aby ustawić równoważny CGColor na layer.borderColor właściwość.

Można to osiągnąć, tworząc kategorię na CALayer, ustawiając ścieżkę klucza na unikatową nową „właściwość” ( borderColorFromUIColor) oraz w kategorii nadpisując odpowiednią metodę ustawiającą ( setBorderColorFromUIColor:).

pkamb
źródło
1

Jest na to znacznie lepszy sposób! Powinieneś użyć @IBInspectable. Sprawdź wpis na blogu Mike'a Woelmera tutaj: https://spin.atomicobject.com/2017/07/18/swift-interface-builder/

W rzeczywistości dodaje tę funkcję do IB w Xcode! Niektóre zrzuty ekranu w innych odpowiedziach sprawiają, że wygląda na to, że pola istnieją w IB, ale przynajmniej w Xcode 9 ich nie ma. Ale śledzenie jego postu spowoduje ich dodanie.

cdeerinck
źródło
Wypróbowałem to podejście i sprawiło, że Xcode był naprawdę wolny. Czy to się wam wszystkim przytrafia?
Meep
0

W przypadku Swifta funkcja nie działa. Aby osiągnąć pożądany rezultat, potrzebujesz obliczonej właściwości:

extension CALayer {
    var borderColorFromUIColor: UIColor {
        get {
            return UIColor(CGColor: self.borderColor!)
        } set {
            self.borderColor = newValue.CGColor
        }
    }
}
Furqan Khan
źródło
0

To działa dla mnie.

Swift 3, Xcode 8.3

Inspektor tożsamości (w tym przypadku UIButton

Rozszerzenie CALayer:

extension CALayer {
var borderWidthIB: NSNumber {
    get {
        return NSNumber(value: Float(borderWidth))
    }
    set {
        borderWidth = CGFloat(newValue.floatValue)
    }
}
var borderColorIB: UIColor? {
    get {
        return borderColor != nil ? UIColor(cgColor: borderColor!) : nil
    }
    set {
        borderColor = newValue?.cgColor
    }
}
var cornerRadiusIB: NSNumber {
    get {
        return NSNumber(value: Float(cornerRadius))
    }
    set {
        cornerRadius = CGFloat(newValue.floatValue)
    }
}

}

Jovan Stankovic
źródło