web-dev-qa-db-fra.com

Comment créer un bouton avec une bordure arrondie dans Swift?

Je construis une application à l'aide de Swift dans la dernière version de Xcode 6 et j'aimerais savoir comment je peux modifier mon bouton afin qu'il puisse avoir une bordure arrondie que je pourrais ajuster si nécessaire. Une fois cela fait, comment puis-je changer la couleur de la bordure sans ajouter d'arrière-plan? En d'autres termes, je veux un bouton légèrement arrondi sans arrière-plan, seulement une bordure de 1 pt d'une certaine couleur.

188
GuiGui23

Utilisez button.layer.cornerRadius, button.layer.borderColor et button.layer.borderWidth. Notez que borderColor requiert une CGColor, donc vous pourriez dire (Swift 3/4):

button.backgroundColor = .clear
button.layer.cornerRadius = 5
button.layer.borderWidth = 1
button.layer.borderColor = UIColor.black.cgColor
437
return true

Effectuer ce travail dans le storyboard (Interface Builder Inspector)

Avec l’aide de IBDesignable, nous pouvons ajouter d’autres options à Interface Builder Inspector for UIButton et les ajuster sur le storyboard. Tout d’abord, ajoutez le code suivant à votre projet.

@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)
        }
    }
}

Ensuite, définissez simplement les attributs des boutons sur le storyboard.

 enter image description here

35
Fangming

J'ai créé une sous-classe UIButton simple qui utilise la variable tintColor pour le texte et les couleurs de la bordure. Lorsque l'arrière-plan est mis en surbrillance, son arrière-plan devient la tintColor.

class BorderedButton: UIButton {

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    layer.borderWidth = 1.0
    layer.borderColor = tintColor.CGColor
    layer.cornerRadius = 5.0
    clipsToBounds = true
    contentEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
    setTitleColor(tintColor, forState: .Normal)
    setTitleColor(UIColor.whiteColor(), forState: .Highlighted)
    setBackgroundImage(UIImage(color: tintColor), forState: .Highlighted)
}
}

Cela utilise une extension UIImage qui crée une image à partir d’une couleur. J’ai trouvé ce code ici: https://stackoverflow.com/a/33675160

Cela fonctionne mieux lorsque vous définissez le type Personnalisé dans le générateur d'interface, car le type de système par défaut modifie légèrement les couleurs lorsque le bouton est en surbrillance.

20
sgib

Cette classe est basée sur tous les commentaires et suggestions des réponses, et peut également être conçue directement à partir de xcode. Copiez dans votre projet et insérez n'importe quel UIButton et utilisez une classe personnalisée. Il vous suffit maintenant de sélectionner la couleur de bordure ou d'arrière-plan dans xcode pour les états normaux et/ou en surbrillance. 

//
//  RoundedButton.Swift
//

import UIKit

@IBDesignable
class RoundedButton:UIButton {

    @IBInspectable var borderWidth: CGFloat = 0 {
        didSet {
            layer.borderWidth = borderWidth
        }
    }
    //Normal state bg and border
    @IBInspectable var normalBorderColor: UIColor? {
        didSet {
            layer.borderColor = normalBorderColor?.CGColor
        }
    }

    @IBInspectable var normalBackgroundColor: UIColor? {
        didSet {
            setBgColorForState(normalBackgroundColor, forState: .Normal)
        }
    }


    //Highlighted state bg and border
    @IBInspectable var highlightedBorderColor: UIColor?

    @IBInspectable var highlightedBackgroundColor: UIColor? {
        didSet {
            setBgColorForState(highlightedBackgroundColor, forState: .Highlighted)
        }
    }


    private func setBgColorForState(color: UIColor?, forState: UIControlState){
        if color != nil {
            setBackgroundImage(UIImage.imageWithColor(color!), forState: forState)

        } else {
            setBackgroundImage(nil, forState: forState)
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        layer.cornerRadius = layer.frame.height / 2
        clipsToBounds = true

        if borderWidth > 0 {
            if state == .Normal && !CGColorEqualToColor(layer.borderColor, normalBorderColor?.CGColor) {
                layer.borderColor = normalBorderColor?.CGColor
            } else if state == .Highlighted && highlightedBorderColor != nil{
                layer.borderColor = highlightedBorderColor!.CGColor
            }
        }
    }

}

//Extension Required by RoundedButton to create UIImage from UIColor
extension UIImage {
    class func imageWithColor(color: UIColor) -> UIImage {
        let rect: CGRect = CGRectMake(0, 0, 1, 1)
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), false, 1.0)
        color.setFill()
        UIRectFill(rect)
        let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}
13
le0diaz

Basé sur @returntrue answer, j'ai réussi à l'implémenter dans Interface Builder.

Pour obtenir le bouton coins arrondis à l'aide d'Interface Builder, ajoutez une clé Path = "layer.cornerRadius" avec Type = "Number" et Value = "10" (ou toute autre valeur requise) dans le "User Defined RunTime Attribute" du Identity Inspector du bouton.

8
Zvi

Vous pouvez utiliser cette sous-classe d'UIButton pour personnaliser UIButton selon vos besoins.

visitez ce dépôt Github pour référence

class RoundedRectButton: UIButton {

    var selectedState: Bool = false

    override func awakeFromNib() {
        super.awakeFromNib()
        layer.borderWidth = 2 / UIScreen.main.nativeScale
        layer.borderColor = UIColor.white.cgColor
        contentEdgeInsets = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    }


    override func layoutSubviews(){
        super.layoutSubviews()
        layer.cornerRadius = frame.height / 2
        backgroundColor = selectedState ? UIColor.white : UIColor.clear
        self.titleLabel?.textColor = selectedState ? UIColor.green : UIColor.white
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        selectedState = !selectedState
        self.layoutSubviews()
    }
}
2
Nikesh Jha
   @IBOutlet weak var yourButton: UIButton! {
        didSet{
            yourButton.backgroundColor = .clear
            yourButton.layer.cornerRadius = 10
            yourButton.layer.borderWidth = 2
            yourButton.layer.borderColor = UIColor.white.cgColor
        }
    }
2
Giang

Je pense que le moyen le plus simple et le plus propre consiste à utiliser un protocole pour éviter les héritages et la répétition de code .. Vous pouvez modifier ces propriétés directement à partir du storyboard 

protocol Traceable {
    var cornerRadius: CGFloat { get set }
    var borderColor: UIColor? { get set }
    var borderWidth: CGFloat { get set }
}

extension UIView: Traceable {

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

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

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

Mettre à jour 

Dans ce link vous pouvez trouver un exemple avec l’utilité du protocole Traceable 

 enter image description here

1
Hamza

ESSAYEZ CECI Bordure à boutons aux coins arrondis

anyButton.backgroundColor = .clear

anyButton.layer.cornerRadius = anyButton.frame.height / 2

anyButton.layer.borderWidth = 1

anyButton.layer.borderColor = UIColor.black.cgColor
0
Raghib Arshi

astuce à part assurez-vous que votre bouton n'est pas une sous-classe d'une classe personnalisée dans le story-board, dans ce cas, votre meilleur emplacement de code devrait être dans la classe personnalisée. La classe UIButton et son exutoire, espérons que cela puisse aider quelqu'un à se demander pourquoi les radios de coin ne s'appliquent pas sur mon bouton à partir du code. 

0
IsPha
@IBOutlet weak var button: UIButton!

...

Je pense que pour le rayon juste ce paramètre:

button.layer.cornerRadius = 5
0
Iryna Batvina