LoginSignup
45
27

More than 5 years have passed since last update.

UIWindowのwindowLevelについて あるいはソフトウェアキーボードより上にViewを表示する方法

Posted at

ソフトウェアキーボードより上にViewを表示したい!と思って方法を調べました。

iOSのソフトウェアキーボードはUIWindow

iOSのソフトウェアキーボードの正体は、keyWindowとは別のUIWindowです。
ということで、独自にUIWindowを生成して表示すれば、キーボードより上にViewを表示することができます。

詳しくはこちら。

UIWindowのサブクラスをわざわざ作る必要はありません。

let currentWindow = UIApplication.sharedApplication().keyWindow
let newWindow = UIWindow(frame:currentWindow.frame)
newWindow.windowLevel = UIWindowLevelNormal
newWindow.addSubview(hogeView)
newWindow.makeKeyAndVisible()

こんな感じでnewWindowを表示できます。
windowを消したいときには、resignKeyWindow() を実行するのではなく、nilを入れる。

windowLevelの話

さて、UIWindow の表示順は、設定された windowLevel で制御されます。
UIWindowLevelはCGFloatのエイリアスです。
UIWindow.h に定数として定義されているのは以下の3種類。

  • UIWindowLevelNormal // = CGFloat(0)
  • UIWindowLevelAlert // = CGFloat(2000)
  • UIWindowLevelStatusBar // = CGFloat(1000)

ここで問題です。
キーボードより上にWindowを表示するためにはどのwindowLevelを設定すればいいでしょうか!?

答え。
全部ダメです。
マジかよ。

ためしにキーボードを表示した状態で、Windowの構成を見てみましょう。

検証環境はiOS9.1です。

検証コード:

UIApplication.sharedApplication().windows

結果:

[<UIWindow: 0x148214bb0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x148218980>; layer = <UIWindowLayer: 0x148215ea0>>,
 <UITextEffectsWindow: 0x146da70d0; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x146da7450>>,
 <UIRemoteKeyboardWindow: 0x149391ce0; frame = (0 0; 320 568); opaque = NO; autoresize = W+H; layer = <UIWindowLayer: 0x149392270>>
]

3つめのUIRemoteKeyboardWindowがソフトウェアキーボード。
iOS開発におけるウィンドウ「UIWindow」の知られざる活用方法とは? #iOS|CodeIQ MAGAZINE
によると、過去のバージョンのiOSではUITextEffectsWindowで表示されていたこともあったようですが…

なにはともあれ、これらのwindowLevelを確認してみると…

検証コード:

UIApplication.sharedApplication().windows.map { $0.windowLevel }

結果:

 [0.0, 1.0, 10000000.0]

10000000.0って何だよ…。

結論

独自のUIWindowをキーボードより上に表示したいなら、10000000.0より大きい数をwindowLevelに設定しましょう。
というか、 UIApplication.sharedApplication().windows をぶん回して、それより大きい数を設定しましょう。

newWindow.windowLevel = UIApplication.sharedApplication().windows.reduce(0, combine: { max($0, $1.windowLevel) }) + 1

みたいに書けばいいんじゃないかな。

45
27
0

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
45
27