¿Es posible establecer las propiedades del borde UIView desde el generador de interfaces?


184

¿Es posible controlar las propiedades del borde UIView (color, grosor, etc.) directamente desde el generador de interfaces o solo puedo hacerlo mediante programación?



1
En caso de que alguien venga de Google como lo hice yo. Para ver esos cambios reflejados en IB, solo necesita crear una subclase de UIView y asignarla a cualquier Vista que desee manipular en IB.
Kanongata

Respuestas:


392

En realidad, puede establecer algunas propiedades de la capa de una vista a través del generador de interfaces. Sé que puedo establecer borderWidth y cornerRadius de una capa a través de xcode. borderColor no funciona, probablemente porque la capa quiere un CGColor en lugar de un UIColor.

Puede que tenga que usar cadenas en lugar de números, ¡pero funciona!

layer.cornerRadius
layer.borderWidth
layer.borderColor

Actualización: layer.masksToBounds = true

ejemplo

Actualización: seleccione el tipo apropiado para Keypath:

ingrese la descripción de la imagen aquí


3
Para usted y Peter DeWeese: uso Xcode 4.6.3 y puedo configurar el tipo de ruta de acceso a "Color" sin implementar una interfaz

39
Lamentablemente, layer.borderColor no se puede configurar de esta manera. Es un CGColorRef, pero ese tipo de valor de color IB es un UIColor.
mrgrieves

12
¡Entonces esto es lo que hace el usuario con los atributos de tiempo de ejecución! Jaja, he estado escribiendo para iOS desde 2011 y nunca supe para qué servían esos campos. Gracias por esta increíble respuesta.
Andy Ibáñez

3
Agradable, pero debe establecer el tipo correcto para cada propiedad. ¡El tipo para, por ejemplo, "layer.cornerRadius" debe establecerse en "Número" en lugar de "Cadena"!
Peter Kreinz

55
Además, no olvide marcar la casilla de verificación "recortar a límites" para que el cornerRadius funcione.
Pierre-Olivier Simonard

183

La respuesta de Rich86Man es correcta, pero puede usar categorías para propiedades proxy como layer.borderColor. (Del convencional C cacao C)

CALayer + XibConfiguration.h:

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>

@interface CALayer(XibConfiguration)

// This assigns a CGColor to borderColor.
@property(nonatomic, assign) UIColor* borderUIColor;

@end

CALayer + XibConfiguration.m:

#import "CALayer+XibConfiguration.h"

@implementation CALayer(XibConfiguration)

-(void)setBorderUIColor:(UIColor*)color
{
    self.borderColor = color.CGColor;
}

-(UIColor*)borderUIColor
{
    return [UIColor colorWithCGColor:self.borderColor];
}

@end

Interface Builder

layer.borderUIColor

El resultado será evidente durante el tiempo de ejecución, no en Xcode.

Editar : también debe establecer layer.borderWidthal menos 1 para ver el borde con el color elegido.

En Swift 2.0:

extension CALayer {
    var borderUIColor: UIColor {
        set {
            self.borderColor = newValue.CGColor
        }

        get {
            return UIColor(CGColor: self.borderColor!)
        }
    }
}

En Swift 3.0:

extension CALayer {
    var borderUIColor: UIColor {
        set {
            self.borderColor = newValue.cgColor
        }

        get {
            return UIColor(cgColor: self.borderColor!)
        }
    }
}

No puedo hacer que esto funcione para mí. El archivo .m se queja de que borderColor tiene que ser borderUIColor y corregirlo, después de hacerlo, aún muestra advertencias y el color del borde no se muestra en tiempo de ejecución. Lo que es diferente en la mía es que tengo @ implementación NameOfFile, no @ implementación CALayer (NameOfFile), no entiendo la parte CALayer, ¿podría explicar eso más por favor
Dave Haigh,

2
@PeterDeWeese great answer! =)
c-villain

1
En realidad, puede usar Número con borderWidth y aceptar un NSNumber. Funciona bien.
Peter DeWeese

1
Esta es definitivamente la mejor solución en mi opinión para resolver el problema de BorderColor. Fantástico uso de categorías!
EricWasTaken

1
Trabajado en Swift!
KOTIOS

81

Respuesta similar a la de iHulk, pero en Swift

Agregue un archivo llamado UIView.swift en su proyecto (o simplemente péguelo en cualquier archivo):

import UIKit

@IBDesignable extension UIView {
    @IBInspectable var borderColor: UIColor? {
        set {
            layer.borderColor = newValue?.cgColor
        }
        get {
            guard let color = layer.borderColor else {
                return nil
            }
            return UIColor(cgColor: color)
        }
    }
    @IBInspectable var borderWidth: CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }
    @IBInspectable var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
            clipsToBounds = newValue > 0
        }
        get {
            return layer.cornerRadius
        }
    }
}

Entonces esto estará disponible en Interface Builder para cada botón, imageView, etiqueta, etc. en el Panel de utilidades> Inspector de atributos:

Inspector de atributos

Nota: el borde solo aparecerá en tiempo de ejecución.


@Gaurav ¿Qué error ves? ¿En qué componente (UIButton, UILabel, etc.) lo está utilizando?
Axel Guilmin

No puedo ayudarte sin más detalles :(
Axel Guilmin

2
Estaba obteniendo bloqueos de Interface Builder con este enfoque hasta que lo eliminé @IBDesignabledesde el comienzo de la extensión.
Albert Bori

1
Eso es asombroso ... ¡Gracias! Estoy usando XCode 8.2.1
bobwki el

1
Muy práctico y ordenado! ¡Gracias!
Karl-John Chow

56

Puede crear una categoría de UIView y agregar esto en el archivo .h de categoría

@property (nonatomic) IBInspectable UIColor *borderColor;
@property (nonatomic) IBInspectable CGFloat borderWidth;
@property (nonatomic) IBInspectable CGFloat cornerRadius;

Ahora agregue esto en el archivo .m

@dynamic borderColor,borderWidth,cornerRadius;

y esto también en. archivo m

-(void)setBorderColor:(UIColor *)borderColor{
    [self.layer setBorderColor:borderColor.CGColor];
}

-(void)setBorderWidth:(CGFloat)borderWidth{
    [self.layer setBorderWidth:borderWidth];
}

-(void)setCornerRadius:(CGFloat)cornerRadius{
    [self.layer setCornerRadius:cornerRadius];
}

ahora verá esto en su guión gráfico para todas las subclases de UIView (UILabel, UITextField, UIImageView, etc.)

ingrese la descripción de la imagen aquí

Eso es ... No es necesario importar la categoría en ningún lugar, solo agregue los archivos de la categoría en el proyecto y vea estas propiedades en el guión gráfico.


2
Compleméntelo con IB_DESIGNABLE para que IB vuelva a dibujar su vista personalizada utilizando el método drawRect: developer.apple.com/library/ios/recipes/…
txulu

3
Eso es genial, si escribe IB_DESIGNABLE en el archivo .h antes de la línea de interfaz, no necesita agregar la línea @dynamic en .m
Jasmeet

@ user1618612 no tiene nada que ver con la resolución, solo establece las propiedades de la capa normal.
iHulk

11

Para Swift 3 y 4 , si está dispuesto a usar IBInspectables, hay esto:

@IBDesignable extension UIView {
    @IBInspectable var borderColor:UIColor? {
        set {
            layer.borderColor = newValue!.cgColor
        }
        get {
            if let color = layer.borderColor {
                return UIColor(cgColor: color)
            }
            else {
                return nil
            }
        }
    }
    @IBInspectable var borderWidth:CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }
    @IBInspectable var cornerRadius:CGFloat {
        set {
            layer.cornerRadius = newValue
            clipsToBounds = newValue > 0
        }
        get {
            return layer.cornerRadius
        }
    }
}

Esta es la mejor solución para mí
Mục Mayng

Gran solución, gracias
Ebtehal___

7

Si bien esto podría establecer las propiedades, en realidad no se refleja en IB. Entonces, si esencialmente está escribiendo código en IB, también podría hacerlo en su código fuente


1
¡Bienvenido a MVC! ¡Usted ve que las propiedades nunca deben estar en código!
Alejandro Iván

2
^ Esto no es lo que es MVC.
Andrew Plummer

1
Teniendo en cuenta que el 95% del tiempo este código va en el controlador, también es MVC, por supuesto, si subclasifica o extiende su vista correctamente, entonces solo su configuración sobre la codificación :-)
Daniele Bernardini

4

Si desea ahorrar tiempo, simplemente use dos UIViewsuno encima del otro, el de la parte posterior es el color del borde y el del frente es más pequeño, lo que da el efecto de borde. Tampoco creo que esta sea una solución elegante, pero si a Apple le importa un poco más, entonces no debería tener que hacer esto.


10
Las soluciones alternativas ahorran tiempo ahora y pierden mucho más tiempo en el futuro.
Lachezar Todorov

0

Es absolutamente posible solo cuando configuras layer.masksToBounds = truey descansas cosas.


-1

Storyboard no funciona para mí todo el tiempo, incluso después de probar toda la solución aquí

Por lo tanto, siempre es la respuesta perfecta es usar el código, solo cree la instancia IBOutlet de UIView y agregue las propiedades

Respuesta corta :

layer.cornerRadius = 10
layer.borderWidth = 1
layer.borderColor = UIColor.blue.cgColor

Respuesta larga :

Esquinas redondeadas de UIView / UIButton, etc.

customUIView.layer.cornerRadius = 10

Espesor de la frontera

pcustomUIView.layer.borderWidth = 2

Color del borde

customUIView.layer.borderColor = UIColor.blue.cgColor

La pregunta es muy específica y pregunta cómo hacerlo desde el generador de interfaces. Tu respuesta es irrelevante.
Shinnyx

-5

Agregue estas 2 líneas de código simples:

self.YourViewName.layer.cornerRadius = 15
self.YourViewName.layer.masksToBounds = true

Funcionará bien

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.