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
UILabel
como lo es para unUITextField
?Si no es así, y necesito convertir mi
UILabel
aUITextField
, ¿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 .