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
let gesture = UILongPressGestureRecognizer(target: self, action: #selector(self.showMenu))
self.addGestureRecognizer(gesture)
}
@objc func showMenu(_ recognizer: UILongPressGestureRecognizer) {
self.becomeFirstResponder()
let menu = UIMenuController.shared
let locationOfTouchInLabel = recognizer.location(in: self)
if !menu.isMenuVisible {
var rect = bounds
rect.origin = locationOfTouchInLabel
rect.size = CGSize(width: 1, height: 1)
menu.showMenu(from: self, rect: rect)
}
}
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
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
.
The sample project on github due to @zoul's answer is the way to go. At the time of this writing, that project does not actually put anything on the clipboard (pasteboard). here is how:
Change @zoul's implementation of this method to:
- (void) copy:(id)sender {
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
pboard.string = self.text;
}
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:
I've made an open source UILabel subclass that shows a UIMenuController with a "Copy" option upon long press:
HTCopyableLabel on GitHub
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
Override the UITextField
instance's textFieldShouldBeginEditing
method, and set it to return NO
in order to disable editing.
Take a look at the UITextFieldDelegate
protocol for more details.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With