Respuestas:
Debe usar la capa de vista para establecer la propiedad del borde. p.ej:
#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;
También debe vincular con QuartzCore.framework para acceder a esta funcionalidad.
__bridge CGColorRef
. Esto no funciona. Tiene que ser [UIColor blackColor].CGColor
como se menciona en la respuesta.
#import <QuartzCore/QuartzCore.h>
Ya no es necesario.
Desde la versión más nueva de Xcode hay una mejor solución para esto:
Con @IBInspectable
usted puede establecer los atributos directamente desde dentro de la Attributes Inspector
.
Esto establece el User Defined Runtime Attributes
para usted:
Hay dos enfoques para configurar esto:
Opción 1 (con actualización en vivo en Storyboard)
MyCustomView
.UIView
.@IBDesignable
(esto hace que la actualización Ver sea activa). *@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
solo funciona cuando se establece al comienzo declass MyCustomView
Opción 2 (no funciona desde Swift 1.2, ver comentarios)
Extienda su clase 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 esta manera, su Vista predeterminada siempre tiene esos campos editables adicionales Attributes Inspector
. Otra ventaja es que no tiene que cambiar la clase MycustomView
cada vez. Sin embargo, un inconveniente de esto es que solo verá sus cambios cuando ejecute su aplicación.
También puede crear un borde con el color de su deseo.
view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;
* r, g, b son los valores entre 0 y 255.
r
, g
y b
probablemente debería ser flotadores; los divisores también deben ser flotadores: r / 255.0
.
Agregue los siguientes @IBInspectables en la extensión 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
}
}
}
Y luego debería poder establecer los atributos borderColor y borderWidth directamente desde el inspector de atributos. Ver imagen adjunta
Cuando uso la solución CALayer de Vladimir, y en la parte superior de la vista, tengo una animación, como un UINavigationController modal que se descarta, veo que ocurren muchos problemas técnicos y problemas de rendimiento de dibujo.
Entonces, otra forma de lograr esto, pero sin los problemas técnicos y la pérdida de rendimiento, es crear una UIView personalizada e implementar el drawRect
mensaje de esta manera:
- (void)drawRect:(CGRect)rect
{
CGContextRef contextRef = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(contextRef, 1);
CGContextSetRGBStrokeColor(contextRef, 255.0, 255.0, 255.0, 1.0);
CGContextStrokeRect(contextRef, rect);
}
setNeedsDisplay
a la vista. Esto obligará a volver a dibujar la UIView e implícitamente volverá a llamar drawRect
. No probado, aunque ...
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
Prueba este código:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];
No sugeriría anular el drawRect debido a que causa un impacto en el rendimiento.
En cambio, modificaría las propiedades de la clase como se muestra a continuación (en su uiview personalizado):
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.layer.borderWidth = 2.f;
self.layer.borderColor = [UIColor redColor].CGColor;
}
return self;
No vi ningún problema técnico al tomar el enfoque anterior, no estoy seguro de por qué poner el initWithFrame detiene estos ;-)
Quería agregar esto a la respuesta de @marczking ( Opción 1 ) como un comentario, pero mi bajo estado en StackOverflow lo impide.
Hice un puerto de la respuesta de @marczking al Objetivo C. Funciona de maravilla, ¡gracias @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 me funciona en 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 no desea editar la capa de una UIView, siempre puede incrustar la vista dentro de otra vista. La vista principal tendría su color de fondo establecido en el color del borde. También sería un poco más grande, dependiendo de qué tan ancho desea que sea el borde.
Por supuesto, esto solo funciona si su vista no es transparente y solo desea un color de borde único. El OP quería el borde en la vista misma, pero esta puede ser una alternativa viable.
Si desea agregar diferentes bordes en diferentes lados, puede agregar una subvista con el estilo específico, es una forma fácil de encontrar.