UIButtonを画像が変化しないように無効化する

開発アプリはどのようなものであれ状態は様々遷移するに違いなく 遷移した状態に依ってはユーザーインターフェースの機能も変化するのは往往にして要請される処です。 其の代表がボタンでしょう。 タップ可能であるからこそのボタンですが 場合に依ってはこのタップを制限したいのも屡々です。 手元の開発アプリはゲームですので ゲームの勝敗が着けば例えばゲームを進める機能を有するボタンは押されて欲しくなくなると言った塩梅です。

iPhoneアプリ作成で利用する XcodeSwift ではボタン機能を有する機能は UIButton クラスで提供されています。 其のような言って見ればボタンクラスですので UIView を継承した UIControl クラスを継承しており此処でボタン足る様々な属性が提供されています。 アップル社の公式開発者用サイトの API ReferenceUIControl - UIKit を見れば様々な機能が用意されているのが分かります。

機能に先立って先ずはボタンが実装されていなければなりません。 手元の開発アプリに於いては以下の如く Asset Catalogで登録した画像 を利用して実装しました。

スポンサーリンク
日付:2017年1月5日
開発機:MacBook Pro(13-inch, Late 2016, 4TB3P)
MacOSバージョン:OS X 10.11.6
Xcodeバージョン:8.2.1
言語:Swift 3
主関連アプリ:Fine Kingdom(邦題:楽小王国)
/* ターンを進めるボタン */
forwardTurnButton = UIButton()
forwardTurnButton.frame = CGRect(x: 0, y: 0, width: btnW, height: btnH)
forwardTurnButton.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
let forwardTurnButtonImg:UIImage = UIImage(named: "TurnButton")!
forwardTurnButton.setBackgroundImage(forwardTurnButtonImg, for: UIControlState.normal)
forwardTurnButton.layer.position = CGPoint(x: xOffset, y:yOffset)
forwardTurnButton.addTarget(self, action: #selector(GameScene.onClickforwardTurnButton), for: .touchUpInside)
self.view!.addSubview(forwardTurnButton)

/* 全て徴収するボタン */
collectAllBtn = UIButton(frame: CGRect(x: 0, y: 0, width: btnW, height: btnH))
let collectAllBtnImg:UIImage = UIImage(named: "CollectAll")!
collectAllBtn.setBackgroundImage(collectAllBtnImg, for: UIControlState.normal)
collectAllBtn.layer.anchorPoint = CGPoint(x: 0.5, y: 0)
collectAllBtn.layer.position = CGPoint(x: xOffset, y: yOffset)
collectAllBtn.addTarget(self, action: #selector(GameScene.collectAllTapGesture(_:)), for: .touchUpInside)
self.view!.addSubview(collectAllBtn)

ゲームの開始時点で Game Start! Tap your red area. のメッセージとともにボタンは下の図の如く青い丸の TURN ボタンと赤い丸の Collect ALL の2つが実装通りに表示されます。

addTargetで付与せられた機能と連携した2つの表示ボタン

斯うして2つ表示されたボタンはそれぞれaddTargetで付与せられた機能と連携しますが 此の連携を先ずは切りたいのでした。 さてでは上のアップル社がUIControlに公式に与えた属性を以下に抜粋してみましょう。

  • state: UIControlState
    The state of the control, specified as a bitmask value.
  • isEnabled: Bool
    A Boolean value indicating whether the control is enabled.
  • isSelected: Bool
    A Boolean value indicating whether the control is in the selected state.
  • isHighlighted: Bool
    A Boolean value indicating whether the control draws a highlight.
  • contentVerticalAlignment: UIControlContentVerticalAlignment
    The vertical alignment of content within the control’s bounds.
  • contentHorizontalAlignment: UIControlContentHorizontalAlignment
    The horizontal alignment of content within the control’s bounds.

上記リスト中にも直ぐ様目に飛び込んで来るのが2番目の isEnabled でしょう。 ブーリアン型ですので真偽値を切り替えて遣れば今回の目的の内 ボタン機能を失わせしめられるのは間違いないでしょう。 ゲームの終了条件を満たした時に上で表示した2つのボタンの機能が効いている場合のみ其れを停止せしめる実装は 従って以下の如くなるでしょう。

if forwardTurnButton.isEnabled && collectAllBtn.isEnabled {
  forwardTurnButton.isEnabled = false
  collectAllBtn.isEnabled = false
}

然るべきタイミングで実行された機能停止の実装は 例えばゲームの勝利条件を満たした場合にはゲームスタート時からメッセージが YOU WIN! へと変じて下の図の如く表示されます。

此の時2つのボタンはタップしても機能しません。 其れを示すかの如く画像は薄く表示されているのが上の図からは見て取れるでしょう。

取り敢えずは此れで目論見は達成されるのでしたがしかし ボタン画像の見た目を変えたくない要請もあるかも知れません。 手元の開発ゲームでは其の必要は感じませんでしたが物の序に 見た目を変えないで機能停止させる方法はないのか立ち止まって検証してみました。

何か目星いものはないかと此れ又アップル社のAPI Referenceを繰って UIControlの子クラスの UIButton クラスのページを眺めていると Button States なる項目に以下引用する記述がありました。

Other properties of this class, such as the adjustsImageWhenHighlighted and adjustsImageWhenDisabled properties, let you alter the default behavior in specific cases.

曰く有りげな名称を目にしてさてはと下の方へページをスクロールして行けば Configuring Button Presentation なる項目が用意され上から3つには如何にも其れらしい以下記すブーリアン型のプロパティが用意されています。

  • adjustsImageWhenHighlighted: Bool
    A Boolean value that determines whether the image changes when the button is highlighted.
  • adjustsImageWhenDisabled: Bool
    A Boolean value that determines whether the image changes when the button is disabled.
  • showsTouchWhenHighlighted: Bool
    A Boolean value that determines whether tapping the button causes it to glow.

先ずは adjustsImageWhenHighlighted なる名称が画像を明るくする属性に嵌まり役な感を受けTURNボタンに効かせるべく 以下の如き一行を上の実装に書き加えましたが結果は変わらず 画像変化に何某かの影響はあるでしょうが今回の目論見には無関係のようです。

forwardTurnButton.adjustsImageWhenHighlighted = false

次に adjustsImageWhenDisabled なる名称に目論見に対する多少の違和感はあるもののしかし 説明自体は其のものを確と突いた印象が感じられれば期待して TURNボタンに効かせるべく 以下の如き一行を上の実装に書き加えましてみました。

forwardTurnButton.adjustsImageWhenDisabled = false

ビルドして得られたのが以下の画像で 青色の丸いTURNボタンのみゲーム終了条件を満たしても画像は変化せず どうやらisEnabledがFalseのとき画像の半透過を無効化出来るプロパティである結果が得られました。

adjustsImageWhenDisabledをFalseにセットしてビルドした結果

此れを受けボタンの機能停止処理の実装は以下の如く書き換えます。

if forwardTurnButton.isEnabled && collectAllBtn.isEnabled {
  forwardTurnButton.adjustsImageWhenDisabled = false
  collectAllBtn.adjustsImageWhenDisabled = false
  forwardTurnButton.isEnabled = false
  collectAllBtn.isEnabled = false
}

ビルドして得られた結果が以下の画像で目論見は達成されました。

目論見の達成されたビルド結果
Fine Kingdom(邦題: 楽小王国)
無料:カテゴリ: ゲーム: 9+ 評価
バージョン: 8.0
リリース: 2017年2月7日
更新: 2020年4月9日
サイズ: 9.3 MB
互換性: iOS 12.0 以降のiPhone、iPod touch に対応。および、macOS 11.0以降とApple M1 チップを搭載したMac に対応。