È possibile impostare le proprietà del bordo UIView dal generatore di interfaccia?


184

È possibile controllare le proprietà dei bordi di UIView (colore, spessore, ecc ...) direttamente dal builder di interfacce o posso farlo solo a livello di programmazione?



1
Nel caso in cui qualcuno venga da Google come ho fatto io. Per vedere le modifiche che si riflettono in IB devi solo creare una sottoclasse di UIView e assegnarla a qualunque View che desideri manipolare in IB.
Kanongata,

Risposte:


392

In realtà è possibile impostare alcune proprietà del livello di una vista tramite il generatore di interfaccia. So che posso impostare borderWidth e cornerRadius di un layer tramite xcode. borderColor non funziona, probabilmente perché il layer vuole un CGColor anziché un UIColor.

Potrebbe essere necessario utilizzare le stringhe anziché i numeri, ma funziona!

layer.cornerRadius
layer.borderWidth
layer.borderColor

Aggiornamento: layer.masksToBounds = true

esempio

Aggiornamento: selezionare il tipo appropriato per Keypath:

inserisci qui la descrizione dell'immagine


3
Per te e Peter DeWeese: utilizzo Xcode 4.6.3 e posso impostare il tipo di chiave di chiamata su "Colore" senza implementare un'interfaccia CALayer

39
Sfortunatamente layer.borderColor non può essere impostato in questo modo. È un CGColorRef, ma quel tipo di valore IB Color è un UIColor.
MrGrieves,

12
Quindi QUESTO è ciò che fanno gli attributi di runtime definiti dall'utente! Haha, scrivo per iOS dal 2011 e non ho mai imparato a cosa servissero quei campi. Grazie per questa fantastica risposta.
Andy Ibanez,

3
Bello, ma devi impostare il tipo corretto per ogni proprietà. Il tipo per es. "Layer.cornerRadius" deve essere impostato su "Numero" anziché "Stringa"!
Peter Kreinz,

5
Inoltre, non dimenticare di selezionare la casella "Clip to bounds" per far funzionare cornerRadius.
Pierre-Olivier Simonard,

183

La risposta di Rich86Man è corretta, ma è possibile utilizzare le categorie per proxy proprietà come layer.borderColor. (Dal convenzionale CocoaPod)

CALayer + XibConfiguration.h:

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>

@interface CALayer(XibConfiguration)

// This assigns a CGColor to borderColor.
@property(nonatomic, assign) UIColor* borderUIColor;

@end

CALayer + XibConfiguration.m:

#import "CALayer+XibConfiguration.h"

@implementation CALayer(XibConfiguration)

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

-(UIColor*)borderUIColor
{
    return [UIColor colorWithCGColor:self.borderColor];
}

@end

Interface Builder

layer.borderUIColor

Il risultato sarà evidente durante il runtime, non in Xcode.

Modifica : devi anche impostare layer.borderWidthalmeno 1 per vedere il bordo con il colore scelto.

In Swift 2.0:

extension CALayer {
    var borderUIColor: UIColor {
        set {
            self.borderColor = newValue.CGColor
        }

        get {
            return UIColor(CGColor: self.borderColor!)
        }
    }
}

In Swift 3.0:

extension CALayer {
    var borderUIColor: UIColor {
        set {
            self.borderColor = newValue.cgColor
        }

        get {
            return UIColor(cgColor: self.borderColor!)
        }
    }
}

Non riesco a farlo funzionare per me. Il file .m si lamenta del fatto che borderColor debba essere borderUIColor e per risolverlo, dopo averlo fatto mostra ancora avvisi e il colore del bordo non viene visualizzato in fase di esecuzione. La cosa diversa dalla mia è che ho @ implementazione NameOfFile, non @ implementazione CALayer (NameOfFile), non capisco la parte CALayer, potresti spiegarlo di più per favore
Dave Haigh,

2
@PeterDeWeese great response! =)
c-villain

1
In realtà puoi usare Number con borderWidth e accettare un NSNumber. Funziona bene
Peter DeWeese,

1
Questa è sicuramente la migliore soluzione secondo me per risolvere il problema di BorderColor. Uso fantastico delle categorie!
EricWas

1
Ha lavorato in Swift!
KOTIOS

81

Risposta simile a quella di iHulk, ma in Swift

Aggiungi un file chiamato UIView.swift nel tuo progetto (o semplicemente incollalo in qualsiasi file):

import UIKit

@IBDesignable extension UIView {
    @IBInspectable var borderColor: UIColor? {
        set {
            layer.borderColor = newValue?.cgColor
        }
        get {
            guard let color = layer.borderColor else {
                return nil
            }
            return UIColor(cgColor: color)
        }
    }
    @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
        }
    }
}

Quindi questo sarà disponibile in Interface Builder per ogni pulsante, imageView, etichetta, ecc. Nel Pannello Utilità> Impostazioni attributi:

Ispettore degli attributi

Nota: il bordo verrà visualizzato solo in fase di esecuzione.


@Gaurav Che errore vedi? Su quale componente (UIButton, UILabel, ecc.) Lo stai usando?
Axel Guilmin,

Non posso aiutarti senza ulteriori dettagli :(
Axel Guilmin,

2
Stavo ottenendo crash di Interface Builder con questo approccio fino a quando non sono stato rimosso @IBDesignabledall'inizio dell'estensione.
Albert Bori,

1
È fantastico ... Grazie! Sto usando XCode 8.2.1
bobwki

1
Molto utile e pulito! Grazie!
Karl-John Chow,

56

Puoi creare una categoria di UIView e aggiungerla nel file .h della categoria

@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;

Ora aggiungi questo nel file .m

@dynamic borderColor,borderWidth,cornerRadius;

e anche questo in. file m

-(void)setBorderColor:(UIColor *)borderColor{
    [self.layer setBorderColor:borderColor.CGColor];
}

-(void)setBorderWidth:(CGFloat)borderWidth{
    [self.layer setBorderWidth:borderWidth];
}

-(void)setCornerRadius:(CGFloat)cornerRadius{
    [self.layer setCornerRadius:cornerRadius];
}

ora lo vedrai nello storyboard per tutte le sottoclassi di UIView (UILabel, UITextField, UIImageView ecc.)

inserisci qui la descrizione dell'immagine

Ecco fatto. Non è necessario importare la categoria ovunque, basta aggiungere i file della categoria nel progetto e vedere queste proprietà nello storyboard.


2
Completalo con IB_DESIGNABLE per fare in modo che IB ridisegni la tua vista personalizzata usando drawRect: method developer.apple.com/library/ios/recipes/…
txulu

3
È fantastico, se scrivi IB_DESIGNABLE nel file .h prima della riga di interfaccia, non è necessario aggiungere la riga @dynamic in .m
Jasmeet,

@ user1618612 non ha nulla a che fare con la risoluzione, sta solo impostando le normali proprietà del layer.
iHulk,

11

Per Swift 3 e 4 , se sei disposto a usare IBInspectables, c'è questo:

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

Questa è la soluzione migliore per me
MĐồc

Ottima soluzione, grazie
Ebtehal___

7

mentre questo potrebbe impostare le proprietà, in realtà non si riflette in IB. Quindi, se essenzialmente stai scrivendo codice in IB, potresti anche farlo nel tuo codice sorgente


1
Benvenuti in MVC! Vedi le proprietà non dovrebbero mai essere nel codice!
Alejandro Iván,

2
^ Questo non è MVC.
Andrew Plummer,

1
Considerando che il 95% delle volte che questo codice viene inserito nel controller, è anche MVC, ovviamente dovresti sottoclassare o estendere correttamente la tua vista quindi la sua giusta configurazione sulla codifica :-)
Daniele Bernardini

4

Se vuoi risparmiare tempo, basta usarne due uno UIViewssopra l'altro, uno sul retro è il colore del bordo e uno davanti più piccolo, dando l'effetto del bordo. Non penso che questa sia una soluzione elegante, ma se Apple si preoccupasse un po 'di più, non dovresti farlo.


10
Le soluzioni alternative consentono di risparmiare tempo e di perdere molto più tempo in futuro.
Lachezar Todorov,

0

È assolutamente possibile solo quando si imposta layer.masksToBounds = truee si riposa roba.


-1

Lo storyboard non funziona sempre per me, anche dopo aver provato tutta la soluzione qui

Quindi è sempre la risposta perfetta sta usando il codice, basta creare l'istanza IBOutlet di UIView e aggiungere le proprietà

Risposta breve :

layer.cornerRadius = 10
layer.borderWidth = 1
layer.borderColor = UIColor.blue.cgColor

Risposta lunga :

Angoli arrotondati di UIView / UIButton ecc

customUIView.layer.cornerRadius = 10

Spessore del bordo

pcustomUIView.layer.borderWidth = 2

Colore del bordo

customUIView.layer.borderColor = UIColor.blue.cgColor

La domanda è molto specifica e chiedi come farlo dall'Interface Builder. La tua risposta è irrilevante.
Shinnyx,

-5

Aggiungi queste 2 semplici righe di codice:

self.YourViewName.layer.cornerRadius = 15
self.YourViewName.layer.masksToBounds = true

Funzionerà benissimo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.