我如何使一个button在Swift中有一个圆形的边框?
我正在使用最新版本的Xcode 6中的swift构build一个应用程序,并想知道如何修改我的button,以便它可以有一个四舍五入的边框,以便在需要时调整自己。 一旦完成,我怎样才能改变边框本身的颜色,而不添加背景? 换句话说,我想要一个没有背景的略微圆angular的button,只有一个特定颜色的1pt边框。
使用button.layer.cornerRadius
, button.layer.borderColor
和button.layer.borderWidth
。 请注意, borderColor
需要一个CGColor
,所以你可以说(Swift 3/4):
button.backgroundColor = .clear button.layer.cornerRadius = 5 button.layer.borderWidth = 1 button.layer.borderColor = UIColor.black.cgColor
我创build了一个简单的UIButton sublcass,它使用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扩展从一个颜色创build一个图像,我发现这里的代码: https : //stackoverflow.com/a/33675160
当设置为在界面生成器中键入自定义时,效果最好,因为当button突出显示时,默认的“系统”types稍微修改了颜色。
这个课程是根据所有的意见和build议的答案,也可以直接从Xcodedevise。 复制到您的项目,并插入任何UIButton并更改为使用自定义类,现在只需从xcodeselect边界或背景颜色为正常和/或突出显示的状态。
// // 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的答案,我设法在Interface Builder中实现它。
使用Interface Builder获得圆angularbutton,在“ Identity Inspector
”的“ User Defined RunTime Attribute
”中添加Type = "Number"
和Value = "10"
(或其他值,如需要)的Key Path = "layer.cornerRadius"
button。
要在故事板(Interface Builder Inspector)中执行此任务
在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) } } }
然后简单地设置故事板上的button的属性。
你可以使用这个UIButton的子类来根据你的需要定制UIButton。
请访问这个github回购作为参考
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() } }
我认为最简单和最干净的方法是使用协议来避免inheritance和代码重复。 您可以直接从故事板更改此属性
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 } } }
更新
在这个链接中,您可以findTraceable协议实用程序的示例