web-dev-qa-db-fra.com

Cocoa Touch: Comment changer la couleur et l'épaisseur de la bordure d'UIView?

J'ai vu dans l'inspecteur que je pouvais changer la couleur de fond, mais j'aimerais aussi changer la couleur et l'épaisseur de la bordure, est-ce possible?

Merci

265
foreyez

Vous devez utiliser le calque de la vue pour définir la propriété de la bordure. par exemple:

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

Vous devez également vous connecter à QuartzCore.framework pour accéder à cette fonctionnalité.

583
Vladimir

Mise à jour Xcode 6

Depuis la dernière version de Xcode, il existe une meilleure solution à cela:

Avec @IBInspectable, vous pouvez définir les attributs directement à partir de dans le Attributes Inspector.

My Custom View @IBInspectable Attributes

Ceci définit le User Defined Runtime Attributes pour vous:

enter image description here

Il y a deux approches pour mettre cela en place:

Option 1 (avec mise à jour en direct dans Storyboard)

  1. Créez MyCustomView.
  2. Cela hérite de UIView.
  3. Définissez @IBDesignable (cela rend la mise à jour de View en direct). *
  4. Définissez vos attributs d'exécution (bordure, etc.) avec @IBInspectable
  5. Changez votre classe de vues en MyCustomView
  6. Modifier dans le panneau Attributs et voir les modifications dans 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
        }
    }
}

* @IBDesignable ne fonctionne que lorsqu'il est défini au début de class MyCustomView

Option 2 (ne fonctionne plus depuis Swift 1.2, voir commentaires)

Étendez votre 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
        }
    }
}

De cette façon, votre vue par défaut toujours contient ces champs supplémentaires modifiables dans Attributes Inspector. Un autre avantage est que vous n'avez pas à changer la classe en MycustomView à chaque fois . Cependant, un inconvénient est que vous ne verrez vos modifications que lorsque vous exécuterez votre application.

39
MMachinegun

Vous pouvez également créer une bordure avec la couleur de votre souhait.

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

* r, g, b sont les valeurs comprises entre 0 et 255.

16
rohan-patel

Ajouter les @IBInspectables suivants dans l'extension 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
    }
  }
}

Et ensuite, vous devriez pouvoir définir les attributs borderColor et borderWidth directement à partir de l'inspecteur Attribute. Voir l'image ci-jointe

Inspecteur d'attributs

9
Bikramjit Singh

Lorsque j'utilise la solution CALayer de Vladimir, et au-dessus de la vue, j'ai une animation, telle qu'un licenciement de contrôleur UINavigation modal, je constate de nombreux problèmes et des problèmes de performances d'affichage.

Donc, une autre façon d’y parvenir, mais sans les problèmes et les pertes de performances, est de créer un UIView personnalisé et d’implémenter le message drawRect comme suit:

- (void)drawRect:(CGRect)rect
{
    CGContextRef contextRef = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(contextRef, 1);
    CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
    CGContextStrokeRect(contextRef, rect);    
}
8
Nicu Surdu
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
6
shaiju mathew

Essayez ce code:

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

Je ne suggérerais pas de passer outre drawRect en raison de son impact négatif sur les performances.

Au lieu de cela, je modifierais les propriétés de la classe comme ci-dessous (dans votre vue personnalisée):

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

Je n'ai vu aucun problème lors de l'approche ci-dessus - je ne sais pas pourquoi le fait d'initialiser initWithFrame les arrête ;-)

4
DEzra

@IBInspectable travaille pour moi sur 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
    }
}
2
anhtran

Je voulais ajouter ceci à la réponse de @ marczking ( Option 1 ) en tant que commentaire, mais mon statut médiocre sur StackOverflow l'empêche.

J'ai fait la réponse d'un port de @ marczking à Objective C. Ça marche comme un charme, merci @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
spencery2

Si vous ne voulez pas éditer la couche d'un UIView, vous pouvez toujours incorporer la vue dans une autre vue. La vue parent aurait pour couleur d'arrière-plan la couleur de bordure. Elle serait également légèrement plus grande, en fonction de la largeur souhaitée de la bordure.

Bien entendu, cela ne fonctionne que si votre vue n'est pas transparente et si vous souhaitez une seule couleur de bordure. Le PO voulait voir la frontière dans la vue elle-même, mais cela pourrait être une alternative viable.

1
Matt Becker

Si vous souhaitez ajouter différentes bordures sur différents côtés, vous pouvez éventuellement ajouter une sous-vue avec le style spécifique.

0
Yuanfei Zhu

couleur de bordure de l'article dans Swift 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
0
Akhrua