web-dev-qa-db-ja.com

Swiftでボタンに丸みのあるボーダーを付けるにはどうすればよいですか?

私はXcode 6の最新版でSwiftを使ってアプリを作成しています、そして私が必要に応じて私が自分自身を調整することができるように私がボタンを変更する方法それが完了したら、背景を追加せずに境界線自体の色を変更する方法を教えてください。言い換えれば、私は背景のない少し丸みのあるボタンが欲しくて、ある色の1ptの境界線だけが欲しいです。

198
GuiGui23

button.layer.cornerRadiusbutton.layer.borderColor、およびbutton.layer.borderWidthを使用してください。 borderColorCGColorを必要とするので、(Swift 3/4)と言えます

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

ストーリーボードでこの仕事をする(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)
        }
    }
}

次にストーリーボードのボタンの属性を設定します。

enter image description here

39
Fangming

テキストと境界線の色にtintColorを使用し、強調表示すると背景がtintColorに変わる単純なUIButtonサブカラスを作成しました。

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

デフォルトのSystem typeはボタンがハイライトされたときに色をわずかに変更するので、interface builderでCustomをtypeに設定すると最も効果的に機能します。

21
sgib

このクラスは、回答に含まれるすべてのコメントと提案に基づいています。また、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
    }
}
13
le0diaz

@returntrueの回答に基づいて、私はそれをInterface Builderで実装することに成功しました。

Interface Builderを使用して角丸ボタンを作成するには、ボタンのPath = "layer.cornerRadius"の「Type = "Number"」に、キーValue = "10"User Defined RunTime AttributeおよびIdentity Inspector(または必要に応じてその他の値)を追加します。

8
Zvi

最も簡単で最もきれいな方法は、継承とコードの繰り返しを避けるためにプロトコルを使用することだと思います。このプロパティはストーリーボードから直接変更できます

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 でトレーサブルプロトコルのユーティリティで例を見つけることができます

enter image description here

3
Hamza

あなたはあなたの必要性に従って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()
    }
}
2
Nikesh Jha
   @IBOutlet weak var yourButton: UIButton! {
        didSet{
            yourButton.backgroundColor = .clear
            yourButton.layer.cornerRadius = 10
            yourButton.layer.borderWidth = 2
            yourButton.layer.borderColor = UIColor.white.cgColor
        }
    }
2
Giang

これを試してみる 角の丸いボタンの枠線

anyButton.backgroundColor = .clear

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

anyButton.layer.borderWidth = 1

anyButton.layer.borderColor = UIColor.black.cgColor
0
Raghib Arshi

念のため、ボタンがストーリーボードのカスタムクラスのサブクラスではないことを確認してください。そのような場合は、コードの最適な場所をカスタムクラスにする必要があります。 UIButtonクラスとそのアウトレットは、なぜコーナーラジオがコードから私のボタンに適用されないのかという疑問を誰かが手助けすることを願います。

0
IsPha
@IBOutlet weak var button: UIButton!

...

私はこのパラメータだけで十分に半径を考える:

button.layer.cornerRadius = 5
0
Iryna Batvina