Afficher le menu copier-coller de l'iPhone sur UILabel
-
pouvons-nous Activer le menu copier-coller pour un
UILabel
comme c'est le cas pour unUITextField
? -
si ce n'est pas le cas, et que je dois convertir mon
UILabel
enUITextField
, Comment puis-je activer le menu couper copier-coller et ne pas permettre que le contenu soit modifié?
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
.
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;
}
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
j'ai fait un open source UILabel sous-classe qui montre un UIMenuController avec une "copie" option sur la longue presse:
HTCopyableLabel on GitHub
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
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.
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:
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 :)
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 .