【发布时间】:2015-01-13 16:35:05
【问题描述】:
我正在使用最新版本的 Xcode 6 中的 swift 构建一个应用程序,我想知道如何修改我的按钮,以便它可以有一个圆形边框,如果需要我可以自行调整。完成后,如何在不添加背景的情况下更改边框本身的颜色?换句话说,我想要一个没有背景的略圆的按钮,只有一个特定颜色的 1pt 边框。
【问题讨论】:
我正在使用最新版本的 Xcode 6 中的 swift 构建一个应用程序,我想知道如何修改我的按钮,以便它可以有一个圆形边框,如果需要我可以自行调整。完成后,如何在不添加背景的情况下更改边框本身的颜色?换句话说,我想要一个没有背景的略圆的按钮,只有一个特定颜色的 1pt 边框。
【问题讨论】:
@IBOutlet weak var yourButton: UIButton! {
didSet{
yourButton.backgroundColor = .clear
yourButton.layer.cornerRadius = 10
yourButton.layer.borderWidth = 2
yourButton.layer.borderColor = UIColor.white.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
}
【讨论】:
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
}
}
【讨论】:
您可以将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
【讨论】:
除了提示,请确保您的按钮不是故事板中任何自定义类的子类,在这种情况下,您的代码最佳位置应该在自定义类中,如果您的按钮是子类,则自因代码只能在自定义类之外工作默认的 UIButton 类和它的出口,希望这可以帮助任何人想知道为什么角落收音机不适用于我的代码按钮。
【讨论】:
@IBOutlet weak var button: UIButton!
...
我认为对于半径来说这个参数就足够了:
button.layer.cornerRadius = 5
【讨论】:
您可以使用 UIButton 的这个子类来根据您的需要自定义 UIButton。
visit this github repo for reference
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()
}
}
【讨论】:
使用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
【讨论】:
titleEdgeInsets。
根据@returntrue 的回答,我设法在 Interface Builder 中实现了它。
要使用 Interface Builder 获得圆角按钮,请在按钮的 Identity Inspector 的“User Defined RunTime Attribute”中添加带有 Type = "Number" 和 Value = "10"(或其他需要的值)的键 Path = "layer.cornerRadius"。
【讨论】:
在故事板中完成这项工作(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)
}
}
}
然后简单地设置故事板上按钮的属性。
【讨论】:
我认为最简单和最干净的方法是使用协议来避免继承和代码重复。 您可以直接从情节提要中更改此属性
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 }
}
}
更新
在这个link你可以找到一个使用Traceable协议的例子
【讨论】:
这个类基于答案中的所有 cmets 和建议,也可以直接从 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
}
}
【讨论】:
UIKit 时导入Foundation 真的就足够了?
我创建了一个简单的 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 扩展从颜色创建图像,我在这里找到了代码:https://stackoverflow.com/a/33675160
在界面生成器中设置为自定义时效果最佳,因为默认系统类型会在按钮突出显示时略微修改颜色。
【讨论】: