在 UILabel 上显示 iPhone 剪切复制粘贴菜单
我们可以像为
UITextField
一样为UILabel
启用剪切复制粘贴菜单吗?如果没有,并且我需要将
UILabel
转换为UITextField
,如何启用剪切复制粘贴菜单并且不允许修改内容?
Can we enable the cut copy paste menu for a
UILabel
as it is for aUITextField
?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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
我在
UILabel
上使用了复制 粘贴菜单,我只需为canBecomeFirstResponder
返回YES
,然后调用>[标签成为FirstResponder]
当所述标签出现在屏幕上时。 至于从canBecomeFirstResponder
返回YES
,您可以使用类别创建自定义子类或修补UILabel
:类别解决方案感觉有点 hackish,但是如果您知道自己在做什么,那么它可能比子类化更容易。 我还在 GitHub 上发布了一个 示例项目,展示了如何显示简单的粘贴板菜单在
UILabel
上。I got the copy & paste menu working on a
UILabel
, I just had to returnYES
forcanBecomeFirstResponder
and later call[label becomeFirstResponder]
when the said label was to come on screen. As for returningYES
fromcanBecomeFirstResponder
, you can create a custom subclass or patchUILabel
using a category: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
.由于 @zoul 的回答,github 上的示例项目是可行的方法。 在撰写本文时,该项目实际上并未在剪贴板(粘贴板)上放置任何内容。 方法如下:
将此方法的 @zoul 实现更改为:
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:
Swift 4 ☻ Xcode 9.2。
通过使用 UIMenuController 我们可以做到这一点。
我创建了
IBDesignable
自定义UILabel
类,您可以直接在情节提要上分配该类输出:
Swift 4 ☻ Xcode 9.2.
By using
UIMenuController
we can do it.I have created
IBDesignable
CustomUILabel
class which you can assign on storyboard directlyOutput:
我制作了一个开源 UILabel 子类,长按时显示带有“复制”选项的 UIMenuController:
GitHub 上的 HTCopyableLabel
I've made an open source UILabel subclass that shows a UIMenuController with a "Copy" option upon long press:
HTCopyableLabel on GitHub
在 Swift 5.0 和 Xcode 10.2 中,
直接在 ViewController 中将复制选项添加到 UILabel 中。
如果您想进一步概括这一点以适用于视图控制器中的多个标签,包括深埋在视图层次结构中的标签,请执行以下操作:
向视图控制器添加一个变量
对于要添加副本的每个标签函数,基本上按照上面答案所说的在 viewDidLoad 中执行的操作。 这是 tableView 单元格内标签的示例:
现在修改上面显示的函数,如下所示
这些保持不变:
如果您有任何问题,另请参阅: https://stackoverflow.com/a/23839272/826946
In Swift 5.0 and Xcode 10.2
Add copy option to your UILabel directly in your ViewController.
If you want to generalize this further to work for more than one label in your view controller, including labels that are buried deep in the view hierarchy, do this:
Add a variable to your view controller
For each label that you want to add the copy function to, do basically what the above answer says to do in viewDidLoad. Here's an example for a label inside a tableView cell:
Now modify the functions shown above as follows
These stay the same:
Also see this if you have any problems: https://stackoverflow.com/a/23839272/826946
Swift 5.3 和 SwiftUI
为了在 SwiftUI 中实现此功能,我们可以使用 pableiros 创建一个带有
的组合的方法UIViewRepresentable
。我们需要对
CopyableLabel
类进行两项更新,因为 iOS 13 中已弃用以下方法。.setTargetRect(_,in:)
.setMenutVisible (_,animated)
我们可以通过使用
.showMenu(from:rect:)
方法轻松解决此问题。这是更新后的
CopyableLabel
类。然后,为了让这个类与 SwiftUI 一起工作,我们所要做的就是创建一个简单的 UIViewRepresentable 。
Swift 5.3 and SwiftUI
To make this work in SwiftUI we can use the method that pableiros created an combine that with a
UIViewRepresentable
.There are two updates that we need to make to the
CopyableLabel
class as the following methods were deprecated in iOS 13..setTargetRect(_,in:)
.setMenutVisible(_,animated)
We can easily fix this by using the
.showMenu(from:rect:)
method instead.Here is the updated
CopyableLabel
class.Then to get this class to work with SwiftUI all we have to do is create a simple
UIViewRepresentable
.如果有人仍然感兴趣,我已经分叉了 zoul 的示例项目并添加了对 ARC(以及其他一些功能)的支持:
https://github.com/zhbrass/UILabel-Clipboard
CopyLabel.h/.m 应该是您要找的
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
2019 ...
节省任何人的打字时间:
就是这么简单!
一个微妙之处:
更好的工程的一个细节:
请注意,我们打开第一响应者:
通常,在带有此类标签的给定屏幕上,您要么会有或不会有这样的可复制链接。
因此,您很可能会看到类似的内容:
因此,事实上,而不是这样:
请务必执行此操作:
(请注意,它不是类似于“return linkTurnedOnCurrently”之类的内容.)
2019 ...
Save anyone typing:
It's that easy!
One subtlety:
One detail for better engineering:
Notice we turn on first responder:
Often, on a given screen with such a label, you either will or won't have a copyable link like this.
So you'll very likely have something like:
Thus, in fact instead of this:
be sure to do this:
(Note that it is not something like "return linkTurnedOnCurrently".)
重写
UITextField
实例的textFieldShouldBeginEditing
方法,并将其设置为返回NO
以禁用编辑。看一下
UITextFieldDelegate< /code>
协议了解更多详细信息。
Override the
UITextField
instance'stextFieldShouldBeginEditing
method, and set it to returnNO
in order to disable editing.Take a look at the
UITextFieldDelegate
protocol for more details.如果你有多行文本,你应该使用
UITextView
设置委托:
它应该会神奇地工作:)
If you have multiline text, you should use
UITextView
Set the delegate:
And it should work magically :)
@benvolioT 的 github 项目 是非常好的复制示例。 对于粘贴,请自定义
canPerformAction:withSender:
。有关更多信息,请参阅示例 CopyPasteTile。
@benvolioT's github project is very good example for copying. And for paste, customize
canPerformAction:withSender:
.For more see example CopyPasteTile.
对于 Swift,你必须实现这个类:
在你的故事板中,只需使用
CopyableLabel
类对UILabel
进行子类化For Swift you have to implement this class:
In your storyboard just subclass the
UILabel
withCopyableLabel
class