Cocoa Touch: come modificare il colore e lo spessore del bordo di UIView?


Risposte:


596

È necessario utilizzare il livello view per impostare la proprietà del bordo. per esempio:

#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;

È inoltre necessario collegarsi a QuartzCore.framework per accedere a questa funzionalità.


C'è un modo per impostare larghezza / colori diversi per ogni lato?
lluismontero,

2
@lluismontero Temo che dovrai creare UIView personalizzato con drawRect: metodo per quello
Vladimir

1
Se lo faccio, e in cima a questa vista ho un'animazione, come un licenziamento modale di UINavigationController, vedo accadere un sacco di problemi, è difficile da descrivere. Se disattivo i bordi, tutto torna alla normalità.
Nicu Surdu,

5
Solo un avvertimento per gli altri. Xcode suggerisce di collegare UIColor a CGColorRef come __bridge CGColorRef. Questo non funziona. Deve essere [UIColor blackColor].CGColorcome indicato nella risposta.
GoodSp33d,

6
#import <QuartzCore/QuartzCore.h>non è più necessario.
significato-importa

43

Aggiornamento Xcode 6

Dalla versione più recente di Xcode esiste una soluzione migliore a questo:

Con @IBInspectableè possibile impostare gli attributi direttamente all'interno della Attributes Inspector.

My Custom View @IBInspectable Attributes

Questo imposta il User Defined Runtime Attributesper te:

inserisci qui la descrizione dell'immagine

Esistono due approcci per configurarlo:

Opzione 1 (con aggiornamento live in Storyboard)

  1. Crea MyCustomView.
  2. Questo eredita da UIView.
  3. Imposta @IBDesignable(questo rende live l'aggiornamento della vista). *
  4. Imposta i tuoi attributi di runtime (bordo, ecc.) Con @IBInspectable
  5. Cambia la tua classe Views in MyCustomView
  6. Modifica nel pannello Attributi e visualizza le modifiche nello Storyboard :)

`

@IBDesignable
class MyCustomView: UIView {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.CGColor
        }
    }
}

* @IBDesignablefunziona solo se impostato all'inizio diclass MyCustomView

Opzione 2 (non funzionante da Swift 1.2, vedi commenti)

Estendi la tua classe UIView:

extension UIView {
    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            layer.masksToBounds = cornerRadius > 0
        }
    }
    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    @IBInspectable var borderColor: UIColor? {
        didSet {
            layer.borderColor = borderColor?.CGColor
        }
    }
}

In questo modo, la visualizzazione predefinita contiene sempre quei campi modificabili aggiuntivi Attributes Inspector. Un altro vantaggio è che non devi cambiare la classe MycustomViewogni volta. Tuttavia, uno svantaggio di questo è che vedrai le tue modifiche solo quando avvierai la tua app.


1
La tua estensione non funziona nell'ultima versione di Xcode ad oggi.
Edgar Aroutiounian,

1
Confermo @EdgarAroutiounian solo per dire che in Swift 1.2 il secondo approccio non funziona più
Sergey Grischyov,

Che dire di Objective-C?
Nik Kov

Guarda la risposta di spencery2 più avanti, si è preso il tempo di scriverlo in Objective-C:
MMachinegun

aggiorna l'estensione per non memorizzare un valore e usa set (valore) {} e ottieni {} per accedere direttamente al livello, quindi funziona.
LightningStryk,

17

Puoi anche creare un bordo con il colore del tuo desiderio.

view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;

* r, g, b sono i valori compresi tra 0 e 255.


6
Vale la pena notare che r, ge bprobabilmente dovrebbe essere float; i divisori devono essere anche carri allegorici: r / 255.0.

no, la sintassi C non è come dici tu. r, geb possono essere int, poiché le promozioni C (e objC IS C) lanceranno int r = 128 per raddoppiare quando si effettua: r / 255.0. A proposito, hai ottenuto il doppio e Clang lancerà su CGFloat.
Ingconti,

10

Aggiungi i seguenti @IBInspectables nell'estensione UIView

extension UIView {

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

  @IBInspectable var borderColor: UIColor? {
    get {
      if let color = layer.borderColor {
        return UIColor(CGColor: color)
      }
      return nil
    }
    set(newValue) {
      layer.borderColor = newValue?.CGColor
    }
  }
}

E quindi dovresti essere in grado di impostare gli attributi borderColor e borderWidth direttamente dalla finestra di ispezione degli attributi. Vedi l'immagine allegata

Ispettore degli attributi


8

Quando utilizzo la soluzione CALayer di Vladimir e, soprattutto, ho un'animazione, come un licenziamento modale di UINavigationController, vedo accadere un sacco di problemi tecnici e problemi di performance di disegno.

Quindi, un altro modo per raggiungere questo obiettivo, ma senza problemi tecnici e perdita di prestazioni, è creare un UIView personalizzato e implementare il drawRectmessaggio in questo modo:

- (void)drawRect:(CGRect)rect
{
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(contextRef, 1);
    CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
    CGContextStrokeRect(contextRef, rect);    
}

@Krish Si memorizza il colore in una variabile e quando è necessario modificare il colore del bordo, si cambia il valore della variabile e si chiama setNeedsDisplaynella vista. Ciò forzerà il ridisegno di UIView e implicitamente richiamerà drawRect. Non testato, però ...
Nicu Surdu,

8
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor

1
Non mi piace che le persone vengano votate senza una spiegazione. Aiuta nessuno.
David DelMonte,

7

Prova questo codice:

view.layer.borderColor =  [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];

4

Non consiglierei di ignorare il drawRect a causa di un colpo di prestazione.

Invece, modificherei le proprietà della classe come di seguito (nella tua vista personalizzata):

  - (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
      self.layer.borderWidth = 2.f;
      self.layer.borderColor = [UIColor redColor].CGColor;
    }
  return self;

Non ho visto alcun difetto durante l'approccio sopra - non so perché inserendo initWithFrame li fermi ;-)


3

Volevo aggiungere questo alla risposta di @ marczking ( Opzione 1 ) come commento, ma il mio modesto stato su StackOverflow lo impedisce.

Ho fatto un port della risposta di @ marczking all'obiettivo C. Funziona come un incantesimo, grazie @marczking!

UIView + Border.h:

#import <UIKit/UIKit.h>

IB_DESIGNABLE
@interface UIView (Border)

-(void)setBorderColor:(UIColor *)color;
-(void)setBorderWidth:(CGFloat)width;
-(void)setCornerRadius:(CGFloat)radius;

@end

UIView + Border.m:

#import "UIView+Border.h"

@implementation UIView (Border)
// Note: cannot use synthesize in a Category

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

-(void)setBorderWidth:(CGFloat)width
{
    self.layer.borderWidth = width;
}

-(void)setCornerRadius:(CGFloat)radius
{
    self.layer.cornerRadius = radius;
    self.layer.masksToBounds = radius > 0;
}

@end

2

@IBInspectable funziona per me su iOS 9, Swift 2.0

extension UIView {

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

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

@IBInspectable var borderColor: UIColor? {
    get {
        if let color = layer.borderColor {
            return UIColor(CGColor: color)
        }
        return nil
    }
    set(newValue) {
        layer.borderColor = newValue?.CGColor
    }
}

1

Se non si desidera modificare il livello di una vista UIV, è sempre possibile incorporare la vista in un'altra vista. La vista padre avrebbe il colore di sfondo impostato sul colore del bordo. Sarebbe anche leggermente più grande, a seconda della larghezza del bordo.

Ovviamente, questo funziona solo se la vista non è trasparente e si desidera solo un singolo colore del bordo. L'OP voleva il confine nella vista stessa, ma questa potrebbe essere una valida alternativa.


0

Se si desidera aggiungere bordi diversi su lati diversi, è possibile aggiungere una sottoview con lo stile specifico è un modo facile da trovare.


0

colore del bordo dell'oggetto in rapido 4.2:

let cell = tableView.dequeueReusableCell(withIdentifier: "Cell_lastOrderId") as! Cell_lastOrder
cell.layer.borderWidth = 1
cell.layer.borderColor = UIColor.white.cgColor
cell.layer.cornerRadius = 10
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.