Cambiar UIButton BorderColor en Storyboard

80

Configuré CornerRadius y BorderWidth para UIbutton en Atributos de tiempo de ejecución definidos por el usuario. Sin agregar layer.borderColor funciona bien y muestra el borde en color negro. Pero cuando agregar layer.borderColor no funciona (no muestra el borde).

ingrese la descripción de la imagen aquí

Mohamed Jaleel Nazir
fuente

Respuestas:

159

Para Swift:

ingrese la descripción de la imagen aquí

Swift 3:

extension UIView {

    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }

    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(cgColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.cgColor
        }
    }
}

Swift 2.2:

extension UIView {

    @IBInspectable var cornerRadius: CGFloat {
        get {
            return layer.cornerRadius
        }
        set {
            layer.cornerRadius = newValue
            layer.masksToBounds = newValue > 0
        }
    }

    @IBInspectable var borderWidth: CGFloat {
        get {
            return layer.borderWidth
        }
        set {
            layer.borderWidth = newValue
        }
    }

    @IBInspectable var borderColor: UIColor? {
        get {
            return UIColor(CGColor: layer.borderColor!)
        }
        set {
            layer.borderColor = newValue?.CGColor
        }
    }
}
Mohamed Jaleel Nazir
fuente
hola, estoy creando la clase CustomeView en el objetivo c, pero no se muestra en mi guión gráfico. Por favor, ayúdame.
Pooja Srivastava
¡Mil gracias por esto! :)
Vijay VS
Gracias, impresionante, perfecto
Abo3atef
1
Sin embargo, XCode (versión 8.3.3 (8E3004b)) no muestra el resultado en la vista previa, ¿es correcto y no hay forma de cambiarlo (excepto crear una vista personalizada)?
Konstantin Berkov
¡Esta es la solución más elegante! ¡Buen trabajo!
Zoltan Vinkler
88

Tengo respuesta. Cambie borderColor en lugar de layer.borderColor :

Fragmento de Xcode

y agregue este código en el archivo .m:

#import <QuartzCore/QuartzCore.h>
@implementation CALayer (Additions)

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

@end

Marque las propiedades en Attribute Inspector

Inspector de atributos

Mohamed Jaleel Nazir
fuente
5
@jithin Lo escribí como una extensión Swift, aquí está el código: extensión CALayer {func setBorderColorFromUIColor (color: UIColor) {self.borderColor = color.CGColor}}
Guy
1
truco funcionó. parcialmente. ¡¡¡¿Cómo diablos obtengo el color del borde negro aunque especifiqué el color rojo? !!!!!! ¿algunas ideas? ¿nadie?
static0886
@ static0886: Fue porque el color que está aplicando no está configurado en el borde. Según tengo entendido, no podemos establecer el color del borde del guión gráfico, ya que esta propiedad no se reflejará en el UIComponent en tiempo de ejecución. Por defecto es de color negro. Si desea realizar una prueba, elimine la propiedad de color de los atributos.
Javeed
Para rapidez, puede configurarlo como: self.button.layer.borderColor = <UIColor.CGColor>
Sam
Esa layer.borderColorFromUIColor funcionó para mí en el storyboard. Gracias.
Ramakrishna
50

Swift 4, Xcode 9.2 : use IBDesignabley IBInspectablepara crear controles personalizados y obtener una vista previa en vivo del diseño en Interface Builder.

Aquí hay un código de muestra en Swift, ubicado justo debajo UIKitde ViewController.swift:

@IBDesignable extension UIButton {

    @IBInspectable var borderWidth: CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
        }
        get {
            return layer.cornerRadius
        }
    }

    @IBInspectable var borderColor: UIColor? {
        set {
            guard let uiColor = newValue else { return }
            layer.borderColor = uiColor.cgColor
        }
        get {
            guard let color = layer.borderColor else { return nil }
            return UIColor(cgColor: color)
        }
    }
}

Si va a Atributos inspeccionables de la vista, debería encontrar estas propiedades visualmente, edite las propiedades:

ingrese la descripción de la imagen aquí

Los cambios también se reflejan en los atributos de tiempo de ejecución definidos por el usuario:

ingrese la descripción de la imagen aquí

¡Corre en tiempo de construcción y listo! Verá su botón redondeado claro con borde.

ingrese la descripción de la imagen aquí

Contras Bulaquena
fuente
Esto me ayudó a lograrlo en el guión gráfico. Su respuesta es muy clara de implementar.
R. Mohan
Esta es la respuesta más precisa para esta pregunta con un ejemplo claramente explicado.
SeaWarrior404
Si pudiera agregar para Objective-C, se lo agradecerá.
Mihir Oza
9

La explicación, tal vez se pierda en algunas de las otras respuestas aquí:

La razón por la que no se establece esta propiedad es que layer.borderColornecesita un valor con tipo CGColor.

¡Pero solo los UIColortipos se pueden configurar a través de los atributos de tiempo de ejecución definidos por el usuario de Interface Builder!

Por lo tanto, debe establecer un UIColor en una propiedad de proxy a través de Interface Builder, luego interceptar esa llamada para establecer el CGColor equivalente a la layer.borderColorpropiedad.

Esto se puede lograr creando una Categoría en CALayer, estableciendo la Ruta de la Clave en una nueva "propiedad" única ( borderColorFromUIColor), y en la categoría anulando el correspondiente setter ( setBorderColorFromUIColor:).

pkamb
fuente
1

¡Hay una manera mucho mejor de hacer esto! Deberías usar @IBInspectable. Consulte la entrada del blog de Mike Woelmer aquí: https://spin.atomicobject.com/2017/07/18/swift-interface-builder/

¡De hecho, agrega la función a IB en Xcode! Algunas de las capturas de pantalla en otras respuestas hacen que parezca que los campos existen en IB, pero al menos en Xcode 9 no. Pero siguiendo su publicación los agregaré.

cdeerinck
fuente
Probé este enfoque e hizo que Xcode fuera realmente lento. ¿Les está pasando a todos ustedes también?
Reunión
0

En el caso de Swift, la función no funciona. Necesitará una propiedad calculada para lograr el resultado deseado:

extension CALayer {
    var borderColorFromUIColor: UIColor {
        get {
            return UIColor(CGColor: self.borderColor!)
        } set {
            self.borderColor = newValue.CGColor
        }
    }
}
Furqan Khan
fuente
0

Esto funciona para mi.

Swift 3, Xcode 8.3

Inspector de identidad (UIButton en este caso

Extensión CALayer:

extension CALayer {
var borderWidthIB: NSNumber {
    get {
        return NSNumber(value: Float(borderWidth))
    }
    set {
        borderWidth = CGFloat(newValue.floatValue)
    }
}
var borderColorIB: UIColor? {
    get {
        return borderColor != nil ? UIColor(cgColor: borderColor!) : nil
    }
    set {
        borderColor = newValue?.cgColor
    }
}
var cornerRadiusIB: NSNumber {
    get {
        return NSNumber(value: Float(cornerRadius))
    }
    set {
        cornerRadius = CGFloat(newValue.floatValue)
    }
}

}

Jovan Stankovic
fuente