Risposte:
È 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à.
__bridge CGColorRef
. Questo non funziona. Deve essere [UIColor blackColor].CGColor
come indicato nella risposta.
#import <QuartzCore/QuartzCore.h>
non è più necessario.
Dalla versione più recente di Xcode esiste una soluzione migliore a questo:
Con @IBInspectable
è possibile impostare gli attributi direttamente all'interno della Attributes Inspector
.
Questo imposta il User Defined Runtime Attributes
per te:
Esistono due approcci per configurarlo:
Opzione 1 (con aggiornamento live in Storyboard)
MyCustomView
.UIView
.@IBDesignable
(questo rende live l'aggiornamento della vista). *@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
funziona 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 MycustomView
ogni volta. Tuttavia, uno svantaggio di questo è che vedrai le tue modifiche solo quando avvierai la tua app.
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.
r
, g
e b
probabilmente dovrebbe essere float; i divisori devono essere anche carri allegorici: r / 255.0
.
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
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 drawRect
messaggio 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);
}
setNeedsDisplay
nella vista. Ciò forzerà il ridisegno di UIView e implicitamente richiamerà drawRect
. Non testato, però ...
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
Prova questo codice:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];
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 ;-)
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
@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
}
}
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.
Se si desidera aggiungere bordi diversi su lati diversi, è possibile aggiungere una sottoview con lo stile specifico è un modo facile da trovare.