Быстро изменить расположение UImenu
Я хочу добавить UIMenu в свое приложение, я практиковался с ним, и теперь у меня вопрос, можно ли установить местоположение
UIMenu
немного выше, чем кнопка, отображающая его в данный момент:
как вы можете видеть на этой фотографии, меню в настоящее время перекрывает панель вкладок, и я хотел установить его немного выше, чем панель вкладок. вот мой код:
let menu = UIMenu(title: "", children: [
UIAction(title: NSLocalizedString("Gallery", comment: ""), image: UIImage(systemName: "folder"), handler: {
(_) in
self.loadPhotoGallery()
})
])
btnMenuExtras.menu = menu
3 ответа
iOS 14+
Начиная с iOS 14
UIControl
имеет метод, который предоставляет точку, к которой прикрепить меню
/// Return a point in this control's coordinate space to which to attach the given configuration's menu.
@available(iOS 14.0, *)
open func menuAttachmentPoint(for configuration: UIContextMenuConfiguration) -> CGPoint
так что вы можете переопределить
UIButton
чтобы предоставить желаемое место для меню (рассчитанное или жестко запрограммированное) относительно самой кнопки (`потому что оно находится в координатном пространстве кнопки) и использовать эту кнопку либо в раскадровке (как класс для управления), либо созданной программно (если вам нужно ввести это где-то):
class MyButton: UIButton {
var offset = CGPoint.zero
override func menuAttachmentPoint(for configuration: UIContextMenuConfiguration) -> CGPoint {
// hardcoded variant
// return CGPoint(x: 0, y: -50)
// or relative to orginal
let original = super.menuAttachmentPoint(for: configuration)
return CGPoint(x: original.x + offset.x, y: original.y + offset.y)
}
}
class ViewController: UIViewController {
@IBOutlet weak var btnMenuExtras: MyButton! // << from storyboard
override func viewDidLoad() {
super.viewDidLoad()
let menu = UIMenu(title: "", children: [
UIAction(title: NSLocalizedString("Gallery", comment: ""), image: UIImage(systemName: "folder"), handler: {
(_) in
// self.loadPhotoGallery()
})
])
// offset is hardcoded for demo simplicity
btnMenuExtras.offset = CGPoint(x: 0, y: -50) // << here !!
btnMenuExtras.menu = menu
}
}
Результат:
Демо подготовлено и протестировано с Xcode 13 / iOS 15
Вы можете использовать метод menuAttachmentPoint для UIControl для UIButton, чтобы найти меню и преобразовать этот UIButton в UIBarButtonItem с помощью расширения ниже
@available(iOS 14.0, *)
open func menuAttachmentPoint(for configuration: UIContextMenuConfiguration) -> CGPoint
extension UIButton {
func toBarButtonItem() -> UIBarButtonItem? {
return UIBarButtonItem(customView: self)
}
}
Я хотел бы расширить ответ @Asperi и @Jayesh Patel о том, как мы можем применить эту технику на
UIBarButtonItem
//
// Technique provided by @Asperi
//
class MyButton: UIButton {
var offset = CGPoint.zero
override func menuAttachmentPoint(for configuration: UIContextMenuConfiguration) -> CGPoint {
// hardcoded variant
// return CGPoint(x: 0, y: -50)
// or relative to orginal
let original = super.menuAttachmentPoint(for: configuration)
return CGPoint(x: original.x + offset.x, y: original.y + offset.y)
}
}
let image = UIImage(systemName: "ellipsis.circle", withConfiguration: UIImage.SymbolConfiguration(scale: .default))
let button = MyButton()
button.setImage(image, for: .normal)
let menu = UIMenu(title: "", children: [
UIAction(title: NSLocalizedString("Gallery", comment: ""), image: UIImage(systemName: "folder"), handler: {
(_) in
})
])
// offset is hardcoded for demo simplicity
button.offset = CGPoint(x: 0, y: 50) // << here !!
//
// This is how we can make UIButton as UIBarButtonItem
//
button.menu = menu
button.showsMenuAsPrimaryAction = true
//
// Technique provided by @Jayesh Patel
//
let threeDotsBarButtonItem = UIBarButtonItem(customView: button)
var items = toolbar.items
items?.append(threeDotsBarButtonItem)
toolbar.items = items