UIMenu 사용해보기
Apple의 미리 알림 앱 화면이다. 내비게이션 우측 상단 버튼을 탭 하면 해당 위치에 메뉴 목록이 나타난다. 지금 하고 있는 프로젝트에 이 메뉴를 적용하고 싶어서 찾아봤는데, ActionSheet를 사용하라는 얘기가 많았다. 그래서 UIAlertController
를 사용했는데, 원하는 화면이 나오지 않았다.
알고보니, UIAlertController(.actionSheet)
는 iPad에서는 위와 같이, 탭한 위치에 팝업? 모달? 형태로 나오고, iOS에서는 기존에 흔히 알고 있는 액션 시트 형태로 나온다더라. 애플에서 오픈하지도 않은 기능을 쓰진 않을 텐데 라는 생각을 해서 개발자 문서를 다시 찾아보니, UIMenu
라고 부른다는 것을 알았다. 유..유레카!
var menuItems: [UIAction] {
return [
UIAction(title: I18N.modify, image: UIImage(systemName: "pencil"), handler: { _ in }),
UIAction(title: I18N.delete, image: UIImage(systemName: "trash"), attributes: .destructive, handler: { _ in })
]
}
UIMenu
는 여러 개의 UIAction
을 갖고 있다. UIAlertController
가 UIAlertAction
을 갖고 있는 것과 비슷하다. handler
에는 해당 메뉴 아이템을 탭 했을 때 어떠한 동작을 처리할 것인지 작성하면 되는데, 빈 값이라도 무조건 써야 한다. handler: nil
이나 아예 handler
를 지워봤는데, 오류가 뜬다.
UIMenu
는 UIKeyCommand
도 가질 수 있는데, 이는 macOS, iPadOS에서 키보드를 사용할 때 단축키로 접근할 수 있게 하는 컴포넌트다.
var menu: UIMenu {
return UIMenu(title: "", image: nil, permalink: nil, options: [], children: menuItems)
}
이렇게 UIAction
목록을 만들고 나서, UIMenu
에 담아주자. 맨 처음 참고했던 문사는 위의 코드처럼 연산 프로퍼티로 작성하는데, Apple 문서를 보면 굳이 연산 프로퍼티로 작성하지 않아도 되는 거 같다.
미리 알림 앱처럼 내비게이션 바 아이템으로 동작하게 하고 싶으면, UIMenu
를 UIBarButtonItem
에 담아서 navigationItem.rightBarButtonItem
으로 넣어주면 된다.
아쉽게도 UIMenu
는 iOS 14.0 버전 이상부터 지원한다. 그래서 나는 분기를 나눠서, iOS 14.0 버전 이하면 UIAlertController(.actionSheet)
를 보여주기로 했다.
if #available(iOS 14.0, *) {
self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "",
image: UIImage(systemName: "ellipsis.circle"),
primaryAction: nil,
menu: menu)
} else {
self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis.circle"),
style: .plain,
target: self,
action: #selector(moreActionTapped))
}
@objc func moreActionTapped(_ sender: UIBarButtonItem) {
let alert = UIAlertController(title: nil, message: I18N.actionsheetMessage, preferredStyle: .actionSheet)
let deleteAction = UIAlertAction(title: I18N.modify, style: .default, handler: { _ in })
let saveAction = UIAlertAction(title: I18N.delete, style: .destructive, handler: { _ in })
let cancelAction = UIAlertAction(title: I18N.cancle, style: .cancel, handler: { _ in })
alert.addAction(deleteAction)
alert.addAction(saveAction)
alert.addAction(cancelAction)
self.present(alert, animated: true, completion: nil)
}
iOS 14.0 | iOS 13.0 |
---|---|
끝!