How can I make a button have a rounded border in Swift?

后端 未结 15 2103
庸人自扰
庸人自扰 2021-01-29 17:50

I\'m building an app using swift in the latest version of Xcode 6, and would like to know how I can modify my button so that it can have a rounded border that I could adjust mys

相关标签:
15条回答
  • 2021-01-29 18:05

    You can subclass UIButton and add @IBInspectable variables to it so you can configure the custom button parameters via the StoryBoard "Attribute Inspector". Below I write down that 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
            }
        }
    
    }
    
    0 讨论(0)
  • 2021-01-29 18:09

    I think the easiest and the cleanest way, is to use protocol to avoid inherit and code repetition. You can change this properties directly from 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 }
        }
    }
    

    Update

    In this link you can find an example with the utility of Traceable protocol

    0 讨论(0)
  • 2021-01-29 18:13

    I have created a simple UIButton sublcass that uses the tintColor for its text and border colours and when highlighted changes its background to the 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)
    }
    }
    

    This makes use of a UIImage extension that creates an image from a colour, I found that code here: https://stackoverflow.com/a/33675160

    It works best when set to type Custom in interface builder as the default System type slightly modifies the colours when the button is highlighted.

    0 讨论(0)
  • 2021-01-29 18:14

    Use button.layer.cornerRadius, button.layer.borderColor and button.layer.borderWidth. Note that borderColor requires a CGColor, so you could say (Swift 3/4):

    button.backgroundColor = .clear
    button.layer.cornerRadius = 5
    button.layer.borderWidth = 1
    button.layer.borderColor = UIColor.black.cgColor
    
    0 讨论(0)
  • 2021-01-29 18:16

    This class is based from all the comments and suggestions in answers, and also can be designable directly from xcode. Copy to your project and insert any UIButton and change to use custom class, now just select border or background color from xcode for normal and/or highlighted states.

    //
    //  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
        }
    }
    
    0 讨论(0)
  • 2021-01-29 18:16
    @IBOutlet weak var yourButton: UIButton! {
        didSet{
            yourButton.backgroundColor = .clear
            yourButton.layer.cornerRadius = 10
            yourButton.layer.borderWidth = 2
            yourButton.layer.borderColor = UIColor.white.cgColor
        }
    }
    
    0 讨论(0)
提交回复
热议问题