Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What is going on with this article?
@hiroism

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

More than 1 year has passed since last update.

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
Help us understand the problem. What is going on with this article?
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
hiroism
LOVE and PEACE https://yapparo.net

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
2
Help us understand the problem. What is going on with this article?