25
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Xcode】ボタンの同時タップを禁止する方法

Last updated at Posted at 2018-02-15

isExclusiveTouchで同時タップを禁止

UIButton を同時にタップすると思わぬ不具合が発生する場合があります。

それを防止するために、UIButtonの同時タップを禁止するisExclusiveTouchという設定があります。 exclusive排他的な という意味なので、isExclusiveTouchタップを排他的にする設定 という意味です(デフォルトは false です)。

下記のプログラムのように、同時タップしてほしくないボタンの isExclusiveTouchtrue にすると、ボタンの同時タップができなくなるので安心です。

 buttonA.isExclusiveTouch = true
 buttonB.isExclusiveTouch = true

Outlet Collectionでほぼ自動

しかし、ボタンが増えると、すべてのボタンに isExclusiveTouch を設定するのは大変です。そんなときに便利なのが Outlet Collection です。

Outlet Collection をつくる方法は簡単です。

通常の Outlet をつくるように、controlキーを押しながらボタンをクリックして、ストーリーボードからソースファイルにぐいっとドラッグします。するとポップアップ画面が表示されるので、 connectionOutlet Collection に変更して name に名前を入力して、 connect ボタンをクリックします。

01.png

あとは、 Outlet Collection に追加したいボタンをcontrolキーを押しながらクリックして、さきほど作成した Outlet Collection のところまでドラッグします。そうすると、ひとつの Outlet Collection に複数のボタンが登録されます。

02.png

ソースファイルでは、 Outlet Collection は下記のようになります。

@IBOutlet var exclusiveButtons: [UIButton]!

UIButton の部分が [UIButton] になっているところからわかるように、 Outlet Collection はアウトレットの配列です。配列であれば for-in がつかえるので、下記のようなコードでいっきに isExclusiveTouchtrue に変更できます。

        for button in exclusiveButtons {
            button.isExclusiveTouch = true
        }
03.png

viewDidLoad などで上の処理を実行すれば、 Outlet Collection に追加しているボタンの同時タップを禁止することができます。

デフォルト設定すれば全自動

shtnkgmさんにコメントをいただいて追記しました。ありがとうございます!

以下のように書くと UIButton 全体にデフォルト値として適用が可能だそうです。つぎに紹介する exclusiveAllTouches メソッドも便利ですが、たとえば viewDidLoad よりあとに動的に追加されたボタンへも反映できるそうです。

なにこれ素敵!

UIButton.appearance().isExclusiveTouch = true

再帰メソッドをつかえば全自動

Outlet Collection も便利ですが、ボタンを追加したときに設定し忘れるかもしれません。そんなときに便利な方法をこちらの記事で紹介していました。

UIButtonなどの同時タップを禁止する再帰メソッド

viewDidLoad などで exclusiveAllTouches メソッドを呼び出せば、再帰的にすべてのボタンを検索して isExclusiveTouchtrue にしてくれます。とてもいいですね。

 extension UIViewController {
 
     func exclusiveAllTouches() {
         self.applyAllViews { $0.isExclusiveTouch = true }
     }
 
     func applyAllViews(apply: (UIView) -> ()) {
         apply(self.view)
         self.applyAllSubviews(self.view, apply: apply)
     }
 
     private func applyAllSubviews(view: UIView, apply: (UIView) -> ()) {
         let subviews = view.subviews as [UIView]
         subviews.map { (view: UIView) -> () in // Swiftのmapって戻り値なくても大丈夫なのね(ちょっと不気味
             apply(view)
             self.applyAllSubviews(view, apply: apply)
         }
     }
 }
25
24
2

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
25
24

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?