LoginSignup
2
2

More than 3 years have passed since last update.

【iOS】UIButtonにグラデーション、サブタイトル、左右アイコンを付ける

Last updated at Posted at 2020-02-18

UIButtonにグラデーション、サブタイトル、左右アイコンを付ける例を紹介。image.png
※ このコードにアイコンは付属しません

コード

import UIKit

class WideButton: UIButton {
    var stackView = UIStackView(frame: .zero)
    var gradientLayer = CAGradientLayer()
    var startColor = UIColor(red: 41/255, green: 171/255, blue: 227/255, alpha: 1)
    var endColor = UIColor(red: 41/255, green: 171/255, blue: 227/255, alpha: 1)
    var title = UILabel()
    var subtitle = UILabel()

    override func layoutSubviews() {
        super.layoutSubviews()
        self.layer.cornerRadius = self.frame.height / 2
        self.setTitleColor(UIColor.white, for: UIControl.State.normal)
        self.titleLabel?.font = UIFont.boldSystemFont(ofSize: 18)
        gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
        title.adjustsFontSizeToFitWidth = true
        title.baselineAdjustment = .alignCenters
        setLabelScale()
        layoutLayerFrame()
    }

    convenience init() {
        self.init(frame: CGRect.zero)
    }

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

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

    func setUp() {
        self.setTitle("", for: UIControl.State.normal)
        stackView.alignment = .firstBaseline
        stackView.distribution = .equalSpacing
        stackView.spacing = 8
        stackView.translatesAutoresizingMaskIntoConstraints = false
        stackView.isUserInteractionEnabled = false
        self.addSubview(stackView)
        self.centerYAnchor.constraint(equalTo: stackView.centerYAnchor).isActive = true
        self.centerXAnchor.constraint(equalTo: stackView.centerXAnchor).isActive = true
        title.font = UIFont.boldSystemFont(ofSize: 18)
        title.textColor = UIColor.white
        title.isHidden = true
        subtitle.font = UIFont.boldSystemFont(ofSize: 15)
        subtitle.textColor = UIColor.white
        subtitle.isHidden = true
        stackView.addArrangedSubview(title)
        stackView.addArrangedSubview(subtitle)
    }

    func setTitle(_ text: String) {
        title.text = text
        title.isHidden = false
        setLabelScale()
    }

    func setSubTitle(_ text: String) {
        subtitle.text = text
        subtitle.isHidden = false
        setLabelScale()
    }

    func setGradientColors(_ start: UIColor, _ end: UIColor) {
        startColor = start
        endColor = end
        gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
    }

    func setLeftIcon(_ imageName: String) {
        if let iconImage =  UIImage(named: imageName) {
            let iconImageView = UIImageView(image: iconImage)
            let iconWidth = iconImage.size.width
            let iconHeight = iconImage.size.height
            iconImageView.frame = CGRect(x: 20, y: (self.frame.height - iconHeight) / 2, width: iconWidth, height: iconHeight)
            iconImageView.autoresizingMask = [.flexibleRightMargin]
            self.addSubview(iconImageView)
        }
    }

    func setRightIcon(_ imageName: String) {
        if let iconImage =  UIImage(named: imageName) {
            let iconImageView = UIImageView(image: iconImage)
            let iconWidth = iconImage.size.width
            let iconHeight = iconImage.size.height
            iconImageView.frame = CGRect(x: self.frame.width - iconWidth - 20, y: (self.frame.height - iconHeight) / 2, width: iconWidth, height: iconHeight)
            iconImageView.autoresizingMask = [.flexibleLeftMargin]
            self.addSubview(iconImageView)
        }
    }

    private func layoutLayerFrame() {
        gradientLayer.frame = self.bounds
        gradientLayer.cornerRadius = self.layer.cornerRadius
        gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
        gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
        gradientLayer.removeFromSuperlayer()
        self.layer.insertSublayer(gradientLayer, at: 0)
    }

    private func setLabelScale() {
        let labelWidth = title.frame.width + subtitle.frame.width
        var scale: CGFloat = 1
        if labelWidth > 0 { scale = (frame.width - 100) / labelWidth }
        if scale < 1 {
            stackView.transform = CGAffineTransform.identity.scaledBy(x: scale, y: scale)
        } else {
            stackView.transform = CGAffineTransform.identity.scaledBy(x: 1, y: 1)
        }
    }
}

使い方

以下のように使えます。

ViewController
@IBOutlet weak var gradientButton: WideButton! {
    didSet {
            gradientButton.setTitle("タイトルです")
            gradientButton.setSubTitle("サブタイトル")
            gradientButton.setLeftIcon("checkIcon")
            gradientButton.setRightIcon("nextIcon")
            gradientButton.setGradientColors(.cyan, .red)
    }
}

image.png
アイコンの呼び出しにはUIImage(named: String)を使っています。
設定したい画像をAssetCatalogに用意してください。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2