iOS14 の Pull-Down Menus

 iOS14 で UIBarButtonItem や UIButton を押した時にプルダウンメニューを表示する機能が追加されました。ActionSheet でメニューを表示している場合は、今後は代わりにこちらを使う機会が増えるのではないかと思います。

使い方

UIMenu と UIAction というオブジェクトを使用します。

UIMenu
iOS13 で追加されたメニューを設定するオブジェクトで、初期化時に以下の引数を指定します。(今回使用する引数のみ取り上げます)

options: 今回はインラインでの表示なので .displayInline を指定します。
children: UIAction の配列。表示するときに要素ごとに区切り線が入ります。

UIAction
UIMenu における各メニューのオブジェクトです。

title: メニュー名を指定します。
image: アイコンを指定します。
attributes: 破壊的アクションの場合は .destructive にすると赤色で表示されます。

UIButton に実装する

UIButton の menu プロパティに UIMenu オブジェクトをセットします。

let items = UIMenu(options: .displayInline, children: [
    UIAction(title: "メニュー3", image: UIImage(systemName: "pencil"), handler: { _ in
        print("メニュー3が押されました")
    }),
    UIAction(title: "メニュー2", image: UIImage(systemName: "envelope"), handler: { _ in
        print("メニュー2が押されました")
    }),
    UIAction(title: "メニュー1", image: UIImage(systemName: "paperplane.fill"), handler: { _ in
        print("メニュー1が押されました")
    }),
])

let destruct = UIAction(title: "削除する", image: UIImage(systemName: "trash"), attributes: .destructive) { _ in }

button.menu = UIMenu(title: "", children: [destruct, items])
button.showsMenuAsPrimaryAction = true

スクリーンショット 2020-10-15 16.26.12

UIButton で表示する際、デフォルトだと長押しでメニューが表示されるので、もしタップしてすぐ表示したい場合は showsMenuAsPrimaryAction プロパティを true にします。

UIBarButtonItem に実装する

UIButton と同じように menu プロパティに UIMenu オブジェクトをセットします。また、UIBarButtonItem はコンストラクタにも menu: の引数が追加されているので、初期化時にセットすることもできます。

遅延表示

メニューを表示するのに少し時間がかかる処理をはさむ場合は、UIDeferredMenuElement というオブジェクトを使用すると遅延表示することができます。

試しに2秒後にメニューを表示してみます。

let deferredMenus = UIMenu(children: [
    UIDeferredMenuElement({ completion in
        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
            let items = [
                UIAction(title: "メニュー3", image: UIImage(systemName: "pencil"), handler: { _ in
                    print("メニュー3が押されました")
                }),
                UIAction(title: "メニュー2", image: UIImage(systemName: "envelope"), handler: { _ in
                    print("メニュー2が押されました")
                }),
                UIAction(title: "メニュー1", image: UIImage(systemName: "paperplane.fill"), handler: { _ in
                    print("メニュー1が押されました")
                })
            ]
            completion([UIMenu(options: .displayInline, children: items)])
        }
    })
])
       
button.menu = deferredMenus

画像2


この記事が気に入ったらサポートをしてみませんか?