UILabel - UIMenuController菜单项的长按手势

时间:2017-07-21 17:57:32

标签: ios swift uilabel uimenucontroller long-press

我需要在整个应用程序中处理UILable上的长按动作/手势,它应该显示这样的菜单,并带有自定义菜单选项:

enter image description here

根据Apple界面指南,文本字段,文本视图,Web视图和图像视图只能启用此菜单。

是否可以在UILabel中为整个应用添加此类操作,并通过添加自己的菜单选项打开自定义菜单。

1 个答案:

答案 0 :(得分:10)

这是一个UILabel子类,用于处理长按以显示UIMenuController。您还可以在菜单控制器中为用例添加更多操作。

import UIKit

class MenuLabel: UILabel {

    override var canBecomeFirstResponder: Bool {
        return true
    }

    // MARK: - Init

    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    private func commonInit() {
        isUserInteractionEnabled = true
        addGestureRecognizer(
            UILongPressGestureRecognizer(
                target: self,
                action: #selector(handleLongPressed(_:))
            )
        )
    }

    // MARK: - Actions

    internal func handleLongPressed(_ gesture: UILongPressGestureRecognizer) {
        guard let gestureView = gesture.view, let superView = gestureView.superview else {
            return
        }

        let menuController = UIMenuController.shared

        guard !menuController.isMenuVisible, gestureView.canBecomeFirstResponder else {
            return
        }

        gestureView.becomeFirstResponder()

        menuController.menuItems = [
            UIMenuItem(
                title: "Custom Item",
                action: #selector(handleCustomAction(_:))
            ),
            UIMenuItem(
                title: "Copy",
                action: #selector(handleCopyAction(_:))
            )
        ]

        menuController.setTargetRect(gestureView.frame, in: superView)
        menuController.setMenuVisible(true, animated: true)
    }

    internal func handleCustomAction(_ controller: UIMenuController) {
        print("Custom action!")
    }

    internal func handleCopyAction(_ controller: UIMenuController) {
        UIPasteboard.general.string = text ?? ""
    }

}

要解决的关键事项是:

  • 确保标签覆盖canBecomeFirstResponder
  • isUserInteractionEnabled设置为true
  • 在长按处理程序中调用gestureView.becomeFirstResponder()

您可以将此标签添加到Interface Builder或在代码中创建它。

希望这有帮助!