UIStackView → UIButton とか、UITableView ベースのクラスとかでそれっぽいのを実装しようとしたけど、微妙に望むものができない。
が、いつまでもこだわっていると先に進めないので、ひとまず UIMenuController とやらを試すことにした・・・
試したが表示されない。
やりたいこととしては UIButton が押されたタイミングで UIMenuController を表示したいけど、表示されない。
SetTargetRect, setMenuVisible, canBecomeFirstResponder, becomeFirstResponder, canPerformAction とか色々書いたけど駄目。
二進も三進もいかないのでコツコツとデバッグログ入れてみると・・・
cut: copy: select: selectAll: paste: delete: _promptForReplace: _transliterateChinese: _showTextStyleOptions: _lookup: _define: _addShortcut: _accessibilitySpeak: _accessibilitySpeakLanguageSelection: _accessibilityPauseSpeaking: _share: makeTextWritingDirectionRightToLeft: makeTextWritingDirectionLeftToRight:
canPerformAction で渡されてくる action が上記のもので、本来メニューで表示したかった #selector で指定したものが渡ってこない。
最初よく考えもせずに UIMenuItem の追加を以下で書いていた
let item1 = UIMenuItem(title: "Google", action: #selector(MenuButton.google))
let item2 = UIMenuItem(title: "Amazon", action: #selector(MenuButton.amazon))
menu.menuItems?.append(item1)
menu.menuItems?.append(item2)
何のことはなく、menuItems が nil なので nil に append しても nil な訳で・・・また基礎的なところでつまづいてしまった;
自動で補完される ? に早く気付けばよかった・・・
動くコードは以下。
class MenuButton: UIButton {
override var canBecomeFirstResponder: Bool { return true }
func showMenu(_ sender: Any?) {
self.becomeFirstResponder()
let menu = UIMenuController.shared
if !menu.isMenuVisible {
menu.arrowDirection = .down
let items:Array<UIMenuItem> = [
UIMenuItem(title: "Google", action: #selector(MenuButton.google)),
UIMenuItem(title: "Amazon", action: #selector(MenuButton.amazon))
]
menu.menuItems = items
menu.setTargetRect(self.bounds, in: self)
menu.setMenuVisible(true, animated: true)
}
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
print("\(action)")
if action == #selector(google) || action == #selector(amazon) {
return true
}
return false
}
func google() {
print("Google")
}
func amazon() {
print("Amazon")
}
}
呼び出す場合は
MenuButton.showMenu()
StoryBoard 経由ならクラス指定を MenuButton にして、
以下を追記してボタンと Touch Up Inside 紐づける。
@IBAction func buttonTouch(sender: Any) {
let button = sender as! MenuButton
button.showMenu(sender)
}