【问题标题】:Change the location of an UImenu in swift快速更改 UImenu 的位置
【发布时间】: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

【问题讨论】:

标签: ios swift uikit uimenu


【解决方案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,将导致工具栏项目大小问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 1970-01-01
    相关资源
    最近更新 更多