Réponses:
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é.
__bridge CGColorRef
. Cela ne fonctionne pas. Il doit être [UIColor blackColor].CGColor
comme mentionné dans la réponse.
#import <QuartzCore/QuartzCore.h>
n'est plus nécessaire.
Depuis la dernière version de Xcode, il existe une meilleure solution:
Avec @IBInspectable
vous pouvez définir des attributs directement à partir de l' intérieur du Attributes Inspector
.
Cela définit le User Defined Runtime Attributes
pour vous:
Il existe deux approches pour configurer cela:
Option 1 (avec mise à jour en direct dans Storyboard)
MyCustomView
.UIView
.@IBDesignable
(cela rend la mise à jour de View en direct). *@IBInspectable
MyCustomView
"
@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 declass MyCustomView
Option 2 (ne fonctionne pas depuis Swift 1.2, voir les 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 contient toujours ces champs modifiables supplémentaires Attributes Inspector
. Un autre avantage est que vous n'avez pas à changer la classe à MycustomView
chaque fois. Cependant, un inconvénient est que vous ne verrez vos modifications que lorsque vous exécutez votre application.
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.
r
, g
et b
devrait probablement être des flotteurs; les diviseurs doivent également être flotteurs: r / 255.0
.
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 puis, vous devriez pouvoir définir les attributs borderColor et borderWidth directement à partir de l'inspecteur d'attributs. Voir l'image ci-jointe
Lorsque j'utilise la solution CALayer de Vladimir, et en plus de la vue, j'ai une animation, comme le rejet d'un modulaire UINavigationController, je vois beaucoup de problèmes se produire et avoir des problèmes de performances de dessin.
Donc, une autre façon d'y parvenir, mais sans les problèmes et la perte de performances, est de créer une UIView personnalisée et d'implémenter le drawRect
message 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);
}
setNeedsDisplay
la vue. Cela forcera le redessin de l'UIView et implicitement sera rappelé drawRect
. Non testé, mais ...
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
Essayez ce code:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];
Je ne suggérerais pas de remplacer le drawRect en raison d'un impact sur les performances.
Au lieu de cela, je modifierais les propriétés de la classe comme ci-dessous (dans votre uiview personnalisé):
- (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 la mise en initWithFrame arrête ces ;-)
Je voulais ajouter ceci à la réponse de @ marczking ( Option 1 ) en tant que commentaire, mais mon statut modeste sur StackOverflow l'empêche.
J'ai fait un portage de la réponse de @ marczking à l'objectif C. Fonctionne 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
@IBInspectable fonctionne 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
}
}
Si vous ne souhaitez pas modifier le calque d'une vue UIV, vous pouvez toujours incorporer la vue dans une autre vue. La couleur parent aurait sa couleur d'arrière-plan définie sur la couleur de la bordure. Il serait également légèrement plus grand, selon la largeur souhaitée de la bordure.
Bien sûr, cela ne fonctionne que si votre vue n'est pas transparente et que vous ne souhaitez qu'une seule couleur de bordure. Le PO voulait la frontière dans la vue elle-même, mais cela peut être une alternative viable.
Si vous souhaitez ajouter une bordure différente sur différents côtés, il peut être facile d'ajouter une sous-vue avec le style spécifique.