はじめに
こんにちはsuzukiです。今回の記事はFull keyboard Accessという機能のONOFFでアプリが想定しない動作を行っていたため、整理をかねてまとめてみました。
フルキーボードアクセス
Full Keyboard Accessとは
iOS13.4で追加された機能です。外部のKeyboardからiPhoneにアクセスしMacと同じようなコントールを行えます。
設定>アクセシビリティ>キーボード>フルキーボードアクセスから変更が可能です。
コントロール例
次の項目に移動する: Tab
前の項目に移動する: Shift+Tab
ホーム画面に移動する: Command+H
Appスイッチャーを開く: Tab+A
今回の問題
下記の条件で、ボタン設定を行った、カスタムViewの関数がよばれないという問題が起きます。
起きる確率は100%ではないため、まだ見えていない条件か例外パターンがあります。
- 前述のフルキーボードアクセスの設定がONである
- Xibで作成したカスタムViewをStoryBoardで配置している
- カスタムViewのボタンにFirstResponderを利用して関数を設定している
同一の関数をViewControllerやAppDelegate等のレスポンスチェーン内に記述すると、そちら関数がよばれます。
そのためカスタムViewが、FirstResponderとして認識されなくなり、カスタムView設定した関数がよばれないという問題が起きているのだと考えております。
対応方法
対応としては、単純にFirstResponderを利用しないというのが良いかと考えております。
ないしはViewController側に、同じメソッドを記述するでも対応は可能かと思います。
再現アプリ
ViewController
Tag0のボタンにFirstResponderから関数を設定
1 2 3 4 5 6 7 8 9 10 11 12 13 | class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } @IBAction func anyButtonDidPush(_ sender: Any) { if let button = sender as? UIButton{ print("ViewController:\(button.tag)") } } } |
ChildView
カスタムView
Tag1のボタンにFilesOwnerから関数を設定
Tag2のボタンにFirstResponderから関数を設定
1 2 3 4 5 6 7 8 9 10 11 12 13 | import UIKit @IBDesignable class ChildView: UIView { ~Xib利用のための描画処理などは省略~ //buttonアクション @IBAction func anyButtonDidPush(_ sender: Any) { if let button = sender as? UIButton{ print("ChildView:\(button.tag)") } } } |
動かしてみた
実際に下記の順番にボタンを押した際の動作を確認してみます。
Tag:0
Tag:1
Tag:2
設定ON
ViewController:0
ChildView:1
ViewController:2
設定OFF
ViewController:0
ChildView:1
ChildView:2
さいごに
なぜ起きるのかという問題は、情報の取得方法などでいろいろ詰まっております。
ほぼほぼ同様の画面で問題が発生しないパターンが見つかっているのでそちらの角度から何か違いが見つかるといいのですが、、、
おそらくですが、フルキーボードアクセスがONの際には、アクセスを行うViewControllerに対して、命令を常に送れる状態にする影響で、サブクラス側のFirstResponderが動作しないようになっているのだと思っております。