ios - español - cocoa touch tutorial
Mostrar el menú de copia de copiar de copiar de iPhone en UILabel (9)
¿Podemos habilitar el menú copiar copiar pegar para un
UILabelcomo lo es para unUITextField?Si no es así, y necesito convertir mi
UILabelaUITextField, ¿cómo puedo habilitar el menú copiar copiar pegar y no permitir que se modifique el contenido?
El proyecto de muestra en github debido a la respuesta de @ zoul es el camino a seguir. En el momento de escribir esto, ese proyecto en realidad no pone nada en el portapapeles (cartón). aquí es cómo:
La implementación de este método de Change @ zoul para:
- (void) copy:(id)sender {
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
pboard.string = self.text;
}
He bifurcado el proyecto de muestra de zoul y he agregado soporte para ARC (y un par de otras características) si alguien todavía está interesado:
github.com/zhbrass/UILabel-Clipboard
CopyLabel.h / .m debería ser lo que estás buscando
He creado una subclase de UILabel de código abierto que muestra un UIMenuController con la opción "Copiar" al presionar prolongadamente:
HTCopyableLabel en GitHub
Para Swift 3 y Swift 4 tienes que implementar esta clase:
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)
}
}
En su guión gráfico solo subclase el UILabel con clase CopyableLabel
Reemplace el método textFieldShouldBeginEditing la instancia textFieldShouldBeginEditing y textFieldShouldBeginEditing para que devuelva NO para deshabilitar la edición.
Eche un vistazo al protocolo UITextFieldDelegate para más detalles.
Si tiene texto de UITextView , debe usar UITextView
Establece el delegado:
func textView(_ textView: UITextView,
shouldChangeTextIn range: NSRange,
replacementText text: String) -> Bool {
return false
}
Y debería funcionar mágicamente :)
UILabel menú copiar y pegar trabajando en un UILabel , solo tuve que devolver YES para canBecomeFirstResponder y luego llamar a [label becomeFirstResponder] cuando dicha etiqueta debía aparecer en la pantalla. En cuanto a devolver YES desde canBecomeFirstResponder , puede crear una subclase o parche personalizado UILabel usando una categoría:
@implementation UILabel (Clipboard)
- (BOOL) canBecomeFirstResponder
{
return YES;
}
@end
La solución de categoría parece un poco hackosa, pero si sabes lo que estás haciendo, podría ser más fácil que crear subclases. También he puesto un proyecto de muestra en GitHub que muestra cómo mostrar un menú simple en un UILabel .
Swift 4 ☻ Xcode 9.2 . Al usar UIMenuController podemos hacerlo.
UILabel clase IBDesignable personalizada de UILabel que puedes asignar en el guión gráfico directamente
@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
}
}
Salida:
El proyecto github de @benvolioT es un muy buen ejemplo para copiar. Y para pegar, personalice canPerformAction:withSender: Para más información, vea el ejemplo CopyPasteTile .