如何在Swift中使按钮具有圆形边框?

如何在Swift中使按钮具有圆形边框?,swift,uibutton,Swift,Uibutton,我正在使用最新版本的Xcode 6中的swift构建一个应用程序,我想知道如何修改我的按钮,使其具有圆形边框,如果需要,我可以自行调整。完成后,如何在不添加背景的情况下更改边框本身的颜色?换句话说,我想要一个没有背景的略圆的按钮,只有一个1pt的特定颜色的边框。使用按钮.layer.cornerRadius,按钮.layer.borderColor和按钮.layer.borderWidth。 请注意,borderColor需要一个CGColor,因此您可以说(Swift 3/4): 我创建了一个

我正在使用最新版本的Xcode 6中的swift构建一个应用程序,我想知道如何修改我的按钮,使其具有圆形边框,如果需要,我可以自行调整。完成后,如何在不添加背景的情况下更改边框本身的颜色?换句话说,我想要一个没有背景的略圆的按钮,只有一个1pt的特定颜色的边框。

使用
按钮.layer.cornerRadius
按钮.layer.borderColor
按钮.layer.borderWidth
。 请注意,
borderColor
需要一个
CGColor
,因此您可以说(Swift 3/4):


我创建了一个简单的UIButton子容器,它使用
tintColor
作为文本和边框颜色,并在突出显示时将其背景更改为
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)
}
}
这利用了UIImage扩展,该扩展从颜色创建图像,我在这里发现了代码:


在interface builder中设置为type Custom(自定义)时效果最佳,因为当按钮高亮显示时,默认系统类型会略微修改颜色。

该类基于答案中的所有注释和建议,也可以直接从xcode中进行设计。复制到您的项目中,插入任意UIButton并更改为使用自定义类,现在只需从xcode中为正常和/或高亮显示状态选择边框或背景色

//
//  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
    }
}

基于@returntrue answer,我设法在Interface Builder中实现了它


要使用Interface Builder获取圆角按钮,请在“
用户定义的运行时属性
中添加带有
Type=“Number”
Value=“10”
(或其他所需值)的键
Path=“layer.cornerRadius”
我认为最简单、最干净的方法是使用协议来避免继承和代码重复。 您可以直接从情节提要更改此属性

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 }
    }
}
更新

在本文中,您可以找到一个使用可跟踪协议的示例


在情节提要中执行此操作(界面生成器检查器)

借助于
IBDesignable
,我们可以为
UIButton
的Interface Builder Inspector添加更多选项,并在情节提要上进行调整。首先,将以下代码添加到项目中

@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)
        }
    }
}
然后简单地设置故事板上按钮的属性


您可以使用UIButton的此子类根据需要自定义UIButton

class RoundedRectButton:UIButton{
变量selectedState:Bool=false
重写func awakeFromNib(){
super.awakeFromNib()
layer.borderWidth=2/UIScreen.main.nativeScale
layer.borderColor=UIColor.white.cgColor
contentEdgeInsets=UIEdgeInsets(顶部:0,左侧:5,底部:0,右侧:5)
}
覆盖func布局子视图(){
super.layoutSubviews()
layer.cornerRadius=frame.height/2
backgroundColor=selectedState?UIColor.white:UIColor.clear
self.titleLabel?.textColor=selectedState?UIColor.green:UIColor.white
}
覆盖func TouchesBegind(Touchs:Set,带有事件:UIEvent?){
selectedState=!selectedState
self.layoutSubviews()
}
}

我认为对于半径来说,这个参数刚好足够:

button.layer.cornerRadius = 5

请确保您的按钮不是story board中任何自定义类的子类,在这种情况下,您的代码的最佳位置应该在自定义类中。如果您的按钮是默认UIButton类的子类,并且是自定义类的出口,则自因代码只能在自定义类之外工作,希望这能帮助任何想知道为什么街角收音机不适用于我的按钮的人

您可以将
UIButton
子类化,并向其添加
@IBInspectable
变量,以便通过情节提要“属性检查器”配置自定义按钮参数。下面我写下那个代码

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

}
试试这个 带圆角的按钮边框

anyButton.backgroundColor = .clear

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

anyButton.layer.borderWidth = 1

anyButton.layer.borderColor = UIColor.black.cgColor

我认为这是最简单的形式

Button1.layer.cornerRadius = 10(Half of the length and width)
Button1.layer.borderWidth = 2

它是UIButton圆角边界的全局方法

class func setRoundedBorderButton(btn:UIButton)
{
   btn.layer.cornerRadius = btn.frame.size.height/2
   btn.layer.borderWidth = 0.5
   btn.layer.borderColor = UIColor.darkGray.cgColor
}

我试过这个,但我有一个小问题,第一个文本是从边界本身开始的,所以它不是很好看,有什么办法可以解决吗this@vinbhai4u尝试使用
titleEdgeInsets
。如何使框大于按钮文本?为按钮创建一个引用iti的出口我想这样使用它,但不起作用:(UIButton.appearance()当导入“<代码> UIKit < /代码>真的足够了吗?@ ReTrtrue:是的,你是对的,基础是不需要的,如果我没有错的话,我是从原来的XCODE基本模板来的。我更新了代码。唯一的事情是,这会使按钮一直循环。也许你可以添加一个角落RA。dius属性也解决了这个问题。这确实有效,但不是Swift特有的。问题明确地问如何通过使用Swift,而不是通过使用故事板或类似的方式来实现预期效果。我的回答不是针对OP,而是针对其他面临我问题的读者。只有找到这篇文章才能解决问题。在我的opi中根据经验和经验,答案不一定与OP所问的内容完全一致,只要它们与OP相关,并提供对读者有用的额外信息。对这些答案投反对票,你就不鼓励有用的答案。虽然这通常是正确的,尤其是对于广泛的问题,但这个问题的性质是明确的。存在一个多重答案通过故事板要求明确解决的问题的数量,如果可能,读者希望有一个利用故事板的解决方案,然后添加“故事板”谷歌搜索词足以显示这些问题。我不是说你的答案不好,而是说你的答案放错了地方。因为我发现这篇文章最接近解决我的问题,所以我把它贴在这里。走你的路意味着
@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
        }
    }

}
anyButton.backgroundColor = .clear

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

anyButton.layer.borderWidth = 1

anyButton.layer.borderColor = UIColor.black.cgColor
Button1.layer.cornerRadius = 10(Half of the length and width)
Button1.layer.borderWidth = 2
import UIKit

@IBDesignable
class RoundedButton: UIButton {
    
    @IBInspectable var cornerRadius: CGFloat = 8
    @IBInspectable var borderColor: UIColor? = .lightGray
    
    override func draw(_ rect: CGRect) {
        layer.cornerRadius = cornerRadius
        layer.masksToBounds = true
        layer.borderWidth = 1
        layer.borderColor = borderColor?.cgColor
        
    }
    
    
}
class func setRoundedBorderButton(btn:UIButton)
{
   btn.layer.cornerRadius = btn.frame.size.height/2
   btn.layer.borderWidth = 0.5
   btn.layer.borderColor = UIColor.darkGray.cgColor
}