Afficher le menu copier-coller de l'iPhone sur UILabel

  1. pouvons-nous Activer le menu copier-coller pour un UILabel comme c'est le cas pour un UITextField ?

  2. si ce n'est pas le cas, et que je dois convertir mon UILabel en UITextField , Comment puis-je activer le menu couper copier-coller et ne pas permettre que le contenu soit modifié?

34
demandé sur Jack 2009-08-07 22:04:35

9 réponses

j'ai eu le menu copier & coller travaillant sur un UILabel , j'ai juste eu à retourner YES pour canBecomeFirstResponder et plus tard appel [label becomeFirstResponder] quand ladite étiquette devait venir sur l'écran. Quant au retour de YES de canBecomeFirstResponder , vous pouvez créer une sous-classe personnalisée ou un patch UILabel en utilisant une catégorie:

@implementation UILabel (Clipboard)

- (BOOL) canBecomeFirstResponder
{
    return YES;
}

@end

la solution de catégorie se sent un peu hackish, mais si vous savez ce que vous faites, il pourrait être plus facile que le sous-classement. J'ai également mis en place un exemple de projet sur GitHub qui montre comment afficher un simple carton menu UILabel .

39
répondu zoul 2010-12-14 08:00:07

le exemple de projet sur github en raison de la réponse de @zoul est la voie à suivre. Au moment de la rédaction du présent article, ce projet ne met en fait rien sur le bloc-notes (pasteboard). voici comment:

modifier la mise en œuvre de cette méthode par @zoul pour:

- (void) copy:(id)sender {
    UIPasteboard *pboard = [UIPasteboard generalPasteboard];
    pboard.string = self.text;  
}
25
répondu benvolioT 2011-02-15 05:46:22

pour Swift 3 et Swift 4 vous devez mettre en œuvre cette classe:

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)
    }
}

dans votre storyboard juste sous-classe le UILabel avec CopyableLabel classe

14
répondu pableiros 2018-04-27 14:37:14

j'ai fait un open source UILabel sous-classe qui montre un UIMenuController avec une "copie" option sur la longue presse:

HTCopyableLabel on GitHub

5
répondu jonsibley 2013-07-30 15:33:25

j'ai bifurqué le projet d'échantillon de zoul et ajouté le soutien pour ARC (et quelques autres caractéristiques) si quelqu'un est toujours intéressé:

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

CopyLabel.h./m devrait être ce que vous cherchez

4
répondu zhbrass 2013-04-26 15:12:34

outrepasse la méthode UITextField de l'instance textFieldShouldBeginEditing , et la positionne pour retourner NO afin de désactiver l'édition.

consultez le protocole UITextFieldDelegate pour plus de détails.

2
répondu Alex Reynolds 2009-08-07 19:01:22

Swift 4" Xcode 9.2 . En utilisant UIMenuController nous pouvons le faire.

j'ai créé IBDesignable Personnalisé UILabel classe que vous pouvez affecter sur storyboard directement

@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
    }
}

sortie:

enter image description here

1
répondu Jack 2018-04-28 00:27:25

si vous avez du texte multiligne, vous devez utiliser UITextView

Définir le délégué:

func textView(_ textView: UITextView,
              shouldChangeTextIn range: NSRange,
              replacementText text: String) -> Bool {
    return false
}

Et cela devrait fonctionner comme par magie :)

1
répondu mukaissi 2018-04-30 23:44:58

le projet github de @benvolioT est un très bon exemple de copie. Et pour la pâte, personnaliser canPerformAction:withSender: . Pour plus de voir l'exemple CopyPasteTile .

0
répondu goodliving 2017-05-23 12:34:30