-
Can we enable the cut copy paste menu for a
UILabel
as it is for aUITextField
?我们可以为UILabel启用剪切复制粘贴菜单,就像UITextField那样吗?
-
If not, and I need to convert my
UILabel
toUITextField
, how can I enable the cut copy paste menu and not allow the content to be modified?如果没有,并且我需要将我的UILabel转换为UITextField,如何启用剪切复制粘贴菜单而不允许修改内容?
9 个解决方案
#1
39
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:
我得到了在UILabel上工作的copy & paste菜单,我只需返回YES作为canBecomeFirstResponder,然后调用[label becomeFirstResponder]当上述标签出现在屏幕上时。对于从canBecomeFirstResponder返回YES,您可以使用一个类别创建一个自定义子类或修补UILabel:
@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
.
类别解决方案感觉有点陈腐,但如果你知道自己在做什么,它可能比子类化更容易。我还在GitHub上做了一个示例项目,演示如何在UILabel上显示一个简单的pasteboard菜单。
#2
24
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:
由于@zoul的答案,github上的样例项目是可行的。在撰写本文时,该项目实际上并没有将任何东西放到剪贴板(粘贴板)上。这里是:
Change @zoul's implementation of this method to:
将@zoul对该方法的实现更改为:
- (void) copy:(id)sender {
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
pboard.string = self.text;
}
#3
12
For Swift 3 and Swift 4 you have to implement this class:
对于Swift 3和Swift 4,您必须执行此类:
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)
}
}
In your storyboard just subclass the UILabel
with CopyableLabel
class
在故事板中,使用CopyableLabel类对UILabel进行子类化
#4
5
I've made an open source UILabel subclass that shows a UIMenuController with a "Copy" option upon long press:
我已经创建了一个开源的UILabel子类,它显示了一个UIMenuController,在长时间按下时有一个“复制”选项:
HTCopyableLabel on GitHub
HTCopyableLabel GitHub上
#5
4
I've forked zoul's sample project and added support for ARC (and a couple of other features) if anyone's still interested:
如果有人还感兴趣的话,我已经放弃了zoul的样例项目,并增加了对ARC(以及其他几个特性)的支持:
https://github.com/zhbrass/UILabel-Clipboard
https://github.com/zhbrass/UILabel-Clipboard
CopyLabel.h/.m should be what you're looking for
CopyLabel.h /。m应该是你要找的
#6
2
Override the UITextField
instance's textFieldShouldBeginEditing
method, and set it to return NO
in order to disable editing.
覆盖UITextField实例的textFieldShouldBeginEditing方法,并将其设置为返回NO以禁用编辑。
Take a look at the UITextFieldDelegate
protocol for more details.
查看UITextFieldDelegate协议了解更多细节。
#7
1
If you have multiline text, you should use UITextView
如果有多行文本,应该使用UITextView
Set the delegate:
设置委托:
func textView(_ textView: UITextView,
shouldChangeTextIn range: NSRange,
replacementText text: String) -> Bool {
return false
}
And it should work magically :)
它应该神奇地发挥作用:
#8
0
@benvolioT's github project is very good example for copying. And for paste, customize canPerformAction:withSender:
. For more see example CopyPasteTile.
@benvolioT的github项目是一个很好的复制例子。对于粘贴,定制canPerformAction:withSender:。更多信息请参见示例CopyPasteTile。
#9
0
Swift 4 ☻ Xcode 9.2. By using UIMenuController
we can do it.
迅速4☻Xcode 9.2。通过使用UIMenuController我们可以做到。
I have created IBDesignable
Custom UILabel
class which you can assign on storyboard directly
我已经创建了IBDesignable自定义UILabel类,您可以在storyboard上直接分配该类
@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:
输出:
#1
39
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:
我得到了在UILabel上工作的copy & paste菜单,我只需返回YES作为canBecomeFirstResponder,然后调用[label becomeFirstResponder]当上述标签出现在屏幕上时。对于从canBecomeFirstResponder返回YES,您可以使用一个类别创建一个自定义子类或修补UILabel:
@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
.
类别解决方案感觉有点陈腐,但如果你知道自己在做什么,它可能比子类化更容易。我还在GitHub上做了一个示例项目,演示如何在UILabel上显示一个简单的pasteboard菜单。
#2
24
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:
由于@zoul的答案,github上的样例项目是可行的。在撰写本文时,该项目实际上并没有将任何东西放到剪贴板(粘贴板)上。这里是:
Change @zoul's implementation of this method to:
将@zoul对该方法的实现更改为:
- (void) copy:(id)sender {
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
pboard.string = self.text;
}
#3
12
For Swift 3 and Swift 4 you have to implement this class:
对于Swift 3和Swift 4,您必须执行此类:
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)
}
}
In your storyboard just subclass the UILabel
with CopyableLabel
class
在故事板中,使用CopyableLabel类对UILabel进行子类化
#4
5
I've made an open source UILabel subclass that shows a UIMenuController with a "Copy" option upon long press:
我已经创建了一个开源的UILabel子类,它显示了一个UIMenuController,在长时间按下时有一个“复制”选项:
HTCopyableLabel on GitHub
HTCopyableLabel GitHub上
#5
4
I've forked zoul's sample project and added support for ARC (and a couple of other features) if anyone's still interested:
如果有人还感兴趣的话,我已经放弃了zoul的样例项目,并增加了对ARC(以及其他几个特性)的支持:
https://github.com/zhbrass/UILabel-Clipboard
https://github.com/zhbrass/UILabel-Clipboard
CopyLabel.h/.m should be what you're looking for
CopyLabel.h /。m应该是你要找的
#6
2
Override the UITextField
instance's textFieldShouldBeginEditing
method, and set it to return NO
in order to disable editing.
覆盖UITextField实例的textFieldShouldBeginEditing方法,并将其设置为返回NO以禁用编辑。
Take a look at the UITextFieldDelegate
protocol for more details.
查看UITextFieldDelegate协议了解更多细节。
#7
1
If you have multiline text, you should use UITextView
如果有多行文本,应该使用UITextView
Set the delegate:
设置委托:
func textView(_ textView: UITextView,
shouldChangeTextIn range: NSRange,
replacementText text: String) -> Bool {
return false
}
And it should work magically :)
它应该神奇地发挥作用:
#8
0
@benvolioT's github project is very good example for copying. And for paste, customize canPerformAction:withSender:
. For more see example CopyPasteTile.
@benvolioT的github项目是一个很好的复制例子。对于粘贴,定制canPerformAction:withSender:。更多信息请参见示例CopyPasteTile。
#9
0
Swift 4 ☻ Xcode 9.2. By using UIMenuController
we can do it.
迅速4☻Xcode 9.2。通过使用UIMenuController我们可以做到。
I have created IBDesignable
Custom UILabel
class which you can assign on storyboard directly
我已经创建了IBDesignable自定义UILabel类,您可以在storyboard上直接分配该类
@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:
输出: