LoginSignup
15
15

More than 3 years have passed since last update.

【iOS】UIButtonにON/OFFのスイッチ処理を1行で書く【Swift】

Last updated at Posted at 2019-03-24

UIButtonに「on/off」のスイッチを付与したい...

けどいちいちフラグ立てるのはスマートじゃない...

それに複数のUIButtonにon/offのスイッチを持たせるとなったらアーッ

ってことで、UIButtonにon/offのスイッチを持たせたい時に、簡単一行でon/offのスイッチを実装するコードを書いたので(誰でもやってるかもしれないけど)晒したいと思います。

sample
button.gif

開発環境

  • Swift5.0
  • Xcode10.1

目的

UIButtonにON/OFFのスイッチ機能を持たせたい時に、下のように書くのはスマートじゃない。

ViewController.swift

    @IBOutlet var label: UILabel!

    var flag: Bool = false

    @IBAction func tappedButton(_ sender: UIButton) {
        if flag == false {
            //ONにする時に走らせたい処理
            label.text = "ONになったよ!"
            flag = true
        } else if flag == true {
            //OFFにする時に走らせたい処理
            label.text = "OFFになったよ!"
            flag = false
        }
    }

ボタン1個だけなら良いかもしれないが、何個ものUIButtonにスイッチ機能を持たせたい時は全部に同じコードを書く羽目になる。あと誰でも考えつきそう

UIButton.switch(on: , off: )みたいな感じで一行で書きたい(切実)

解決法:UIControlのisSelectedプロパティを利用してExtensionを書けば良い(2019年5月更新)

そんなわけで解決法を「Extensionでなんとか実装できないかなー...」と思って頑張ってみたんですがダメでした()

どうしてもUIButtonのインスタンスに状態を保持するプロパティを持たせる必要があったので、インスタンスプロ>パティを追加することができないExtensionでは実装は難しそうです。Extensionで出来る方法あればぜひ教え>てください(懇願)

Extensionで出来ました(白目)
UIButtonのスーパークラスであるUIControlが、「isSelected」という選択された状態を保持するプロパティを持ってました()
クラスを作る必要はなかったというか愚策だったというか、無知でしたすいません(土下座)

というわけでUIButtonのExtensionで改めて書くとこんな感じになります。

ViewController.swift

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBOutlet var label: UILabel!

    @IBAction func tappedButton(_ sender: UIButton) {

        sender.switchAction(onAction: {
            self.label.text = "ONになったよ!"
        }) {
            self.label.text = "OFFになったよ!"
        }
    }

}

extension UIButton {

    func switchAction(onAction: @escaping ()->Void, offAction: @escaping ()->Void) {

        //選択状態を反転
        self.isSelected = !self.isSelected

        switch self.isSelected {
        case true:
            //ONにする時に走らせたい処理
            onAction()
        case false:
            //OFFにする時に走らせたい処理
            offAction()
        }

    }
}

これをそのままコピペして、Storyboardで@IBAction接続しているUIButtonのクラスにselectedSwitchを指定してあげれば動きます。(あとテスト用のlabelも@IBOutlet接続してるのでそれもお忘れなく)

ちなみにUIControl.isSelectedプロパティは「選択された状態=Buttonが押されたらONにする」という仕様なので、「ON状態のButtonをOFF」にするという処理は自分で書く必要があります。

//extension UIButton {....
//func switchAction(...

選択状態を反転ONだったらOFFOFFだったらONに切り替える処理を入れてます

self.isSelected = !self.isSelected

//switch ...

そんなこんなでこのExtensionでどのUIButtonでも一行でon/offスイッチが書けるようになりました。

他に良い方法あれば教えて頂けると嬉しいです!

15
15
1

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
15
15