Help us understand the problem. What is going on with this article?

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

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に用意してください。

hiroism
LOVE and PEACE
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした