Respostas:
Você precisa usar a camada da vista para definir a propriedade da borda. por exemplo:
#import <QuartzCore/QuartzCore.h>
...
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth = 3.0f;
Você também precisa vincular ao QuartzCore.framework para acessar esta funcionalidade.
__bridge CGColorRef
. Isso não funciona. Precisa ser [UIColor blackColor].CGColor
como mencionado na resposta.
#import <QuartzCore/QuartzCore.h>
não é mais necessário.
Desde a versão mais recente do Xcode, existe uma solução melhor para isso:
Com @IBInspectable
você pode definir atributos diretamente de dentro do Attributes Inspector
.
Isso define User Defined Runtime Attributes
para você:
Existem duas abordagens para configurar isso:
Opção 1 (com atualização ao vivo no Storyboard)
MyCustomView
.UIView
.@IBDesignable
(isso ativa a atualização do View). *@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
só funciona quando definido no início doclass MyCustomView
Opção 2 (não funciona desde o Swift 1.2, ver comentários)
Estenda sua 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
}
}
}
Dessa forma, sua visualização padrão sempre possui esses campos editáveis extras Attributes Inspector
. Outra vantagem é que você não precisa mudar de classe MycustomView
sempre. No entanto, uma desvantagem disso é que você só verá suas alterações quando executar o aplicativo.
Você também pode criar uma borda com a cor do seu desejo.
view.layer.borderColor = [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1.0].CGColor;
* r, g, b são os valores entre 0 e 255.
r
, g
e b
provavelmente deve ser flutuadores; os divisores também deve ser floats: r / 255.0
.
Adicione a seguinte extensão @IBInspectables na 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 você poderá definir os atributos borderColor e borderWidth diretamente do inspetor de Atributos. Ver imagem em anexo
Quando uso a solução CALayer de Vladimir e, no topo da tela, tenho uma animação, como um UINavigationController modal descartando, vejo muitas falhas acontecendo e tendo problemas de desempenho de desenho.
Portanto, outra maneira de conseguir isso, mas sem as falhas e a perda de desempenho, é criar um UIView personalizado e implementar a drawRect
mensagem da seguinte maneira:
- (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 exibição. Isso forçará o redesenho do UIView e implicitamente será chamado novamente drawRect
. Não testado, tho ...
view.layer.borderWidth = 1.0
view.layer.borderColor = UIColor.lightGray.cgColor
Tente este código:
view.layer.borderColor = [UIColor redColor].CGColor;
view.layer.borderWidth= 2.0;
[view setClipsToBounds:YES];
Eu não sugeriria substituir o drawRect devido a causar um impacto no desempenho.
Em vez disso, eu modificaria as propriedades da classe como abaixo (na sua visualização personalizada):
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.layer.borderWidth = 2.f;
self.layer.borderColor = [UIColor redColor].CGColor;
}
return self;
Não vi nenhuma falha ao adotar a abordagem acima - não sei por que colocar o initWithFrame os interrompe ;-)
Eu queria adicionar isso à resposta de @ marczking ( opção 1 ) como um comentário, mas meu status humilde no StackOverflow está impedindo isso.
Eu fiz um porto da resposta de @ marczking para o Objetivo C. Funciona como charme, obrigado @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
O @IBInspectable está funcionando para mim no 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 você não quiser editar a camada de um UIView, sempre poderá incorporar a vista em outra. A visualização principal teria sua cor de fundo definida para a cor da borda. Também seria um pouco maior, dependendo da largura que você deseja que a borda tenha.
Obviamente, isso só funciona se sua visualização não for transparente e você desejar apenas uma única cor de borda. O OP queria a fronteira na própria visualização, mas essa pode ser uma alternativa viável.
Se você deseja adicionar bordas diferentes em lados diferentes, pode ser uma subvisão com o estilo específico, é uma maneira fácil de criar.