大家好,这里是程序员阿山哥🤓今天给大家分享通过UIMenuController来实现UILabel的长按复制文本功能。
开发环境
Xcode 13.2.1
iOS 15.2
import UIKit
class MenuLabel: UILabel {
override func awakeFromNib() {
super.awakeFromNib()
// 要打开UILabel的用户交互开关,默认是关闭的
self.isUserInteractionEnabled = true
// 添加一个长按的手势
let longGes = UILongPressGestureRecognizer(target: self, action: #selector(contentLongPressed(gestureRecognizer:)))
addGestureRecognizer(longGes)
}
@objc private func contentLongPressed(gestureRecognizer:UILongPressGestureRecognizer) {
// 长按结束状态时,执行功能
if gestureRecognizer.state == .ended {
becomeFirstResponder()
// 一个App只能有一个UIMenuController,所以通过单例来获得UIMenuController实例
let menu = UIMenuController.shared
// 创建一个名为“复制”的UIMenuItem,并设置对应的selector
let copy = UIMenuItem(title: "复制", action: #selector(copyText(menuItem:)))
menu.menuItems = [copy] // 这是一个数组,支持多个UIMenuItem
// 显示UIMenuController
menu.showMenu(from: self, rect: bounds)
}
}
override var canBecomeFirstResponder: Bool {
// 配置当前Label能成为第一响应者
true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(copyText(menuItem:)) {
// 配置是否允许Action执行,这个影响menu点击后的响应
return true
}
return false
}
@objc private func copyText(menuItem: UIMenuItem) {
// 实现复制到剪贴板功能
UIPasteboard.general.string = self.text
}
}
除了自己实现UIMenuItem对应的Action Selector,系统默认也有对应的功能,在UIResponderStandardEditActions
协议里
@objc private func contentLongPressed(gestureRecognizer:UILongPressGestureRecognizer) {
if gestureRecognizer.state == .ended {
becomeFirstResponder()
// 拿出菜单控制器单例
let menu = UIMenuController.shared
// 显示菜单控制器,默认是不可见状态
menu.showMenu(from: self, rect: bounds)
}
}
// 省略部分代码,请参考上面的代码
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(copy(_:)) {
// 匹配copy(_:)方法
return true
}
return false
}
override func copy(_ sender: Any?) {
// 重写UIResponderStandardEditActions协议里的copy方法
UIPasteboard.general.string = self.text
}
注意,直接对于UILabel实例进行UIMenuController配置,我发现未能实现功能,需要自己实现一个UILabel子类,在子类里实现UIMenuController的对应功能。当需要的时候,使用这个子类,就能实现UIMenuController的功能了。