今回は、UIButton に Activity Indicator を追加する方法についてです。
ページにボタンがあって、ページ読み込み中はそのボタンにローディングアイコンが表示される、という挙動をさせたくて実装しました。
参考にさせていただいた記事はこちら。
Set Activity Indicator in UIButton in Swift 3 – Mobikul
https://mobikul.com/set-activity-indicator-uibutton-swift-3/
サンプルコードはこちらです。
必要な部分だけを抜粋していますので、それ以外は適宜変更してください。
class ViewController: UIViewController {
@IBOutlet weak var button: UIButton!
var activityIndicator: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
self.button.addTarget(self, action: #selector(self.tapButton(_:)), for: .touchUpInside)
self.showSpinning()
}
@objc func tapButton(_ sender: UIButton) {
self.hideSpinning()
}
public func showSpinning() {
if (activityIndicator == nil) {
activityIndicator = UIActivityIndicatorView()
activityIndicator.hidesWhenStopped = true
activityIndicator.color = UIColor.gray
}
self.button.setImage(nil, for: .normal)
activityIndicator.translatesAutoresizingMaskIntoConstraints = false
self.button.addSubview(activityIndicator)
// ローディングアイコンを中央寄せ
let xCenterConstraint = NSLayoutConstraint(item: self.button!, attribute: .centerX, relatedBy: .equal, toItem: activityIndicator, attribute: .centerX, multiplier: 1, constant: 0)
self.button.addConstraint(xCenterConstraint)
let yCenterConstraint = NSLayoutConstraint(item: self.button!, attribute: .centerY, relatedBy: .equal, toItem: activityIndicator, attribute: .centerY, multiplier: 1, constant: 0)
self.button.addConstraint(yCenterConstraint)
activityIndicator.startAnimating()
}
public hideSpinning() {
activityIndicator.stopAnimating()
self.button.setImage(UIImage(named: "image"), for: .normal)
}
}
上記を実装すると、ページが表示された時にはボタンにローディングアイコンが表示されており、ボタンをタップするとローディングが消え、指定した画像がボタンに表示されます。
意外と大事なのが 22行目の self.button.setImage(nil, for: .normal) でした。
上記のサンプルコードでは大丈夫ですが、例えばもともとボタンに画像を設定している状態から、ローディングアイコンを表示する時には、こちらのコードがないとローディングアイコンとボタン画像の両方が表示されてしまい、大変見にくかったです。
なので、ボタンに設定するものが、画像→ローディングアイコン→画像 というように変化する可能性がある場合は、self.button.setImage(nil, for: .normal) の記述をお忘れなく。
以上、Swift の UIButton に Activity Indicator を追加する方法についてでした。
ご参考になれば幸いです。