UILabel - Long press gesture for menu item of UIMenuController

我们两清 提交于 2019-12-11 07:32:20

问题


I need to handle long press action/gesture on UILable, in an entire app, and it should show a menu like this, with custom menu options:

As per apple interface guideline a text field, a text view, a web view, and an image view can only enable this menu.

Is it feasible to add such action in UILabel for the entire app and open custom menu by adding own menu options, with existing?


回答1:


Here is a UILabel subclass that handles long pressing to show the UIMenuController. You can also add more actions the the menu controller for use case.

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 ?? ""
    }

}

Key things to takeaway from this are:

  • making sure the label overrides canBecomeFirstResponder
  • isUserInteractionEnabled set to true
  • calling gestureView.becomeFirstResponder() in the long press handler

You can add this label to Interface Builder or create it in code.

Hope this helps!



来源:https://stackoverflow.com/questions/45243947/uilabel-long-press-gesture-for-menu-item-of-uimenucontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!