Show iPhone cut copy paste menu on UILabel

前端 未结 12 1223
半阙折子戏
半阙折子戏 2020-11-30 21:05
  1. Can we enable the cut copy paste menu for a UILabel as it is for a UITextField?

  2. If not, and I need to convert my UIL

相关标签:
12条回答
  • 2020-11-30 21:19

    @benvolioT's github project is very good example for copying. And for paste, customize canPerformAction:withSender:. For more see example CopyPasteTile.

    0 讨论(0)
  • 2020-11-30 21:22

    For Swift you have to implement this class:

    import UIKit
    
    class CopyableLabel: UILabel {
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            self.sharedInit()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            self.sharedInit()
        }
    
        func sharedInit() {
            self.isUserInteractionEnabled = true
            self.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(self.showMenu)))
        }
    
        @objc func showMenu(sender: AnyObject?) {
            self.becomeFirstResponder()
    
            let menu = UIMenuController.shared
    
            if !menu.isMenuVisible {
                menu.setTargetRect(bounds, in: self)
                menu.setMenuVisible(true, animated: true)
            }
        }
    
        override func copy(_ sender: Any?) {
            let board = UIPasteboard.general
    
            board.string = text
    
            let menu = UIMenuController.shared
    
            menu.setMenuVisible(false, animated: true)
        }
    
        override var canBecomeFirstResponder: Bool {
            return true
        }
    
        override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
            return action == #selector(UIResponderStandardEditActions.copy)
        }
    }
    

    In your storyboard just subclass the UILabel with CopyableLabel class

    0 讨论(0)
  • 2020-11-30 21:26

    I've made an open source UILabel subclass that shows a UIMenuController with a "Copy" option upon long press:

    HTCopyableLabel on GitHub

    0 讨论(0)
  • 2020-11-30 21:29

    I got the copy & paste menu working on a UILabel, I just had to return YES for canBecomeFirstResponder and later call [label becomeFirstResponder] when the said label was to come on screen. As for returning YES from canBecomeFirstResponder, you can create a custom subclass or patch UILabel using a category:

    @implementation UILabel (Clipboard)
    
    - (BOOL) canBecomeFirstResponder
    {
        return YES;
    }
    
    @end
    

    The category solution feels a bit hackish, but if you know what you’re doing it might be easier than subclassing. I have also put up a sample project on GitHub that shows how to display a simple pasteboard menu on an UILabel.

    0 讨论(0)
  • 2020-11-30 21:29

    I've forked zoul's sample project and added support for ARC (and a couple of other features) if anyone's still interested:

    https://github.com/zhbrass/UILabel-Clipboard

    CopyLabel.h/.m should be what you're looking for

    0 讨论(0)
  • 2020-11-30 21:33

    Swift 4 ☻ Xcode 9.2. By using UIMenuController we can do it.

    I have created IBDesignable Custom UILabel class which you can assign on storyboard directly

    @IBDesignable
    class TapAndCopyLabel: UILabel {
    
        override func awakeFromNib() {
            super.awakeFromNib()
            //1.Here i am Adding UILongPressGestureRecognizer by which copy popup will Appears
            let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(_:)))
            self.addGestureRecognizer(gestureRecognizer)
            self.isUserInteractionEnabled = true
        }
    
        // MARK: - UIGestureRecognizer
        @objc func handleLongPressGesture(_ recognizer: UIGestureRecognizer) {
            guard recognizer.state == .recognized else { return }
    
            if let recognizerView = recognizer.view,
                let recognizerSuperView = recognizerView.superview, recognizerView.becomeFirstResponder()
            {
                let menuController = UIMenuController.shared
                menuController.setTargetRect(recognizerView.frame, in: recognizerSuperView)
                menuController.setMenuVisible(true, animated:true)
            }
        }
        //2.Returns a Boolean value indicating whether this object can become the first responder
        override var canBecomeFirstResponder: Bool {
            return true
        }
        //3.Here we are enabling copy action
        override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
            return (action == #selector(UIResponderStandardEditActions.copy(_:)))
    
        }
        // MARK: - UIResponderStandardEditActions
        override func copy(_ sender: Any?) {
            //4.copy current Text to the paste board
            UIPasteboard.general.string = text
        }
    }
    

    Output:

    0 讨论(0)
提交回复
热议问题