開発メモ

開発関係のメモをいろいろと。たぶん。

枠線付きのボタン

UIButtonに枠線をつける方法はいろんなところで紹介されていますが、どれもいまいち満足できなかったので、自分で作ってみました。

f:id:see_ku:20160225222956p:plain

動作を確認した環境

環境 情報
Xcode 7.2.1 (7C1002)
iOS 9.2
Swift 2.1.1
Date 2016/2/25

できる事

以下のような機能が実装されています。

  • 押したときに枠線の色がちゃんと変わる
  • currentTitleColorから自動で色を設定
  • disableにした時の色も自動で設定
  • アラートが表示されたときの色変更にも対応
  • Storyboardから枠線の太さ/コーナー半径の変更に対応

特にすごい事はやってません。

ソースコード

こんな感じになりました。

import UIKit

/// 枠線付きのボタン
@IBDesignable
public class SK4BorderButton: UIButton {

    @IBInspectable var borderWidth: CGFloat = 1.0 {
        didSet {
            layer.borderWidth = borderWidth
            setNeedsDisplay()
        }
    }

    @IBInspectable var cornerRadius: CGFloat = 4.0 {
        didSet {
            layer.cornerRadius = cornerRadius
            setNeedsDisplay()
        }
    }

    override public var enabled: Bool {
        didSet {
            layer.borderColor = currentTitleColor.CGColor
        }
    }

    override public var highlighted: Bool {
        didSet {
            let col = currentTitleColor
            let key = "borderColor"

            if highlighted {
                layer.borderColor = col.colorWithAlphaComponent(0.2).CGColor
                layer.removeAnimationForKey(key)

            } else {
                layer.borderColor = col.CGColor
                let anim = CABasicAnimation(keyPath: key)
                anim.duration = 0.2
                anim.fromValue = col.colorWithAlphaComponent(0.2).CGColor
                anim.toValue = col.CGColor
                layer.addAnimation(anim, forKey: key)
            }
        }
    }

    override public init(frame: CGRect) {
        super.init(frame: frame)
        setupBorder()
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupBorder()
    }

    override public func tintColorDidChange() {
        super.tintColorDidChange()
        layer.borderColor = currentTitleColor.CGColor
    }

    public func setupBorder() {
        layer.borderWidth = borderWidth
        layer.cornerRadius = cornerRadius
        layer.borderColor = currentTitleColor.CGColor
        clipsToBounds = true
    }
}