快速更改 UImenu 的位置
Posted
技术标签:
【中文标题】快速更改 UImenu 的位置【英文标题】:Change the location of an UImenu in swift 【发布时间】:2021-08-20 20:40:47 【问题描述】:我想在我的应用程序中添加一个 UIMenu,我正在练习它,现在有一个问题,是否可以将 UIMenu
的位置设置为比当前显示的按钮高一点:
正如您在这张照片中看到的那样,菜单当前覆盖标签栏,我想将其设置为比标签栏高一点。 这是我的代码:
let menu = UIMenu(title: "", children: [
UIAction(title: NSLocalizedString("Gallery", comment: ""), image: UIImage(systemName: "folder"), handler:
(_) in
self.loadPhotoGallery()
)
])
btnMenuExtras.menu = menu
【问题讨论】:
是否可以提供x/y相对偏移,或者x/y绝对屏幕位置来弹出UIMenu? @CheokYanCheng 可能不可能,除非你克隆它 - 看看github.com/christianselig/ChidoriMenu 【参考方案1】:我想扩展@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
【讨论】:
【参考方案2】:您可以使用 UIControl 的 menuAttachmentPoint 方法为 UIButton 定位菜单并将该 UIButton 转换为 UIBarButtonItem 通过使用波纹管扩展
@available(ios 14.0, *)
open func menuAttachmentPoint(for configuration: UIContextMenuConfiguration) -> CGPoint
extension UIButton
func toBarButtonItem() -> UIBarButtonItem?
return UIBarButtonItem(customView: self)
【讨论】:
谢谢。能够将 UIButton 包裹在 UIBarButtonItem 周围是一种有用的技术。【参考方案3】:iOS 14+
Sinse 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 准备和测试的演示
【讨论】:
感谢您的宝贵意见。但是,对于工具栏中的按钮,我们通常使用UIBarButtonItem
,它不是从UIControl
继承的。 (我发现可以将 UIButton 添加到 UIToolbar。但我不确定使用 UIButton 而不是 UIBarButtonItem 可能产生的副作用)
好的。我弄清楚了使用UIButton
而不是UIBarButtonItem
的不良副作用是什么。使用UIButton
而不是UIBarButtonItem
,将导致工具栏项目大小问题。以上是关于快速更改 UImenu 的位置的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UIMenu 内的 UIAction 中更改图标颜色? [复制]