Comment puis-je faire un bouton avec une bordure arrondie dans Swift?

Je construis une application en utilisant swift dans la dernière version de Xcode 6 et je voudrais savoir comment je peux modifier mon bouton pour 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 elle-même sans y append un arrière-plan? En d’autres termes, je veux un bouton légèrement arrondi sans arrière-plan, seulement une bordure 1pt d’une certaine couleur.

Utilisez button.layer.cornerRadius , button.layer.borderColor et button.layer.borderWidth . Notez que borderColor nécessite un CGColor , vous pouvez donc dire (Swift 3/4):

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

J’ai créé une simple sous-classe UIButton qui utilise la tintColor de tintColor pour ses couleurs de texte et de bordure et, lorsqu’elle est mise en surbrillance, modifie son arrière-plan pour 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

Il fonctionne mieux lorsqu’il est configuré pour taper 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 mis en surbrillance.

Pour effectuer ce travail dans le storyboard (Inspecteur d’Interface Builder)

Avec l’aide d’ IBDesignable , nous pouvons append d’autres options à Inspector d’Interface Builder pour 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 atsortingbuts des boutons sur le storyboard.

entrer la description de l'image ici

Cette classe est basée sur tous les commentaires et suggestions dans les réponses, et peut également être conçue directement à partir de xcode. Copiez dans votre projet et insérez un UIButton et modifiez-le pour utiliser une classe personnalisée. Sélectionnez maintenant la couleur de bordure ou d’arrière-plan de 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 } } 

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

Pour obtenir le bouton des coins arrondis à l’aide d’Interface Builder, ajoutez un Path = "layer.cornerRadius" clé Path = "layer.cornerRadius" avec Type = "Number" et Value = "10" (ou toute autre valeur requirejse) dans ” User Defined RunTime AtsortingbuteUser Defined RunTime Atsortingbute le bouton.

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

visitez ce rep pris 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, with event: UIEvent?) { selectedState = !selectedState self.layoutSubviews() } } 
  @IBOutlet weak var yourButton: UIButton! { didSet{ yourButton.backgroundColor = .clear yourButton.layer.cornerRadius = 10 yourButton.layer.borderWidth = 2 yourButton.layer.borderColor = UIColor.white.cgColor } } 
 @IBOutlet weak var button: UIButton! 

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

 button.layer.cornerRadius = 5 

en tant que côté, assurez-vous que votre bouton n’est pas une sous-classe d’une classe personnalisée dans un storyboard, dans ce cas votre meilleur emplacement de code devrait être dans la classe personnalisée. UIButton classe et sortie de celui-ci, espérons que cela peut aider quelqu’un se demande pourquoi la radio de coin ne s’applique pas sur mon bouton à partir du code.

Je pense que le moyen le plus simple et le plus propre est d’utiliser un protocole pour éviter les répétitions d’inheritance et de code. Vous pouvez modifier ces propriétés directement depuis le 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 lien, vous pouvez trouver un exemple avec l’utilité du protocole Traceable

entrer la description de l'image ici

Vous pouvez personnaliser votre bouton et append IBInspectable var pour pouvoir le définir à partir de “Inspecteur d’atsortingbuts” de StoryBoard. Ci-dessous, j’écris ce code.

 @IBDesignable class BHButton: UIButton { /* // Only override draw() if you perform custom drawing. // An empty implementation adversely affects performance during animation. override func draw(_ rect: CGRect) { // Drawing code } */ @IBInspectable lazy var isRoundRectButton : Bool = false @IBInspectable public var cornerRadius : CGFloat = 0.0 { didSet{ setUpView() } } @IBInspectable public var borderColor : UIColor = UIColor.clear { didSet { self.layer.borderColor = borderColor.cgColor } } @IBInspectable public var borderWidth : CGFloat = 0.0 { didSet { self.layer.borderWidth = borderWidth } } // MARK: Awake From Nib override func awakeFromNib() { super.awakeFromNib() setUpView() } override func prepareForInterfaceBuilder() { super.prepareForInterfaceBuilder() setUpView() } func setUpView() { if isRoundRectButton { self.layer.cornerRadius = self.bounds.height/2; self.clipsToBounds = true } else{ self.layer.cornerRadius = self.cornerRadius; self.clipsToBounds = true } } }