最近项目中,用到了复制,剪切的功能,这里记录一下
系统自带的input视图的话,是默认有这个功能的,我们现在长按一个label,来实现这个功能。
先说一下UIMenuController,这个就是长按之后,会弹出的那个黑黑的框,如图
先在xib上创建一个label(这里就是copyNumberLabel),设置isUserInteractionEnabled为true,下边就直接上代码
先创建一个长按手势
let tap:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(showMenu(_:)))
copyNumberLabel.addGestureRecognizer(tap)
手势方法实现
func showMenu(_ sender: UILongPressGestureRecognizer) {
if sender.state == .began {//判断是手势状态,如果不写,你会发现松开手势之后还会再一次触发这个方法
self.becomeFirstResponder()//这个必须写,不写就不会显示
menu = UIMenuController.shared
let item:UIMenuItem = UIMenuItem(title: "复制", action: #selector(copyText))//设置显示的item
menu.menuItems = [item]
menu.setTargetRect((sender.view?.frame)!, in: self.view)
menu.setMenuVisible(true, animated: true)//显示UIMenuController
}
}
接下来实现点击item的实现方法
let original:String = copyNumberLabel.text!//原始字符串
let count = original.characters.count
let index = original.index(original.startIndex, offsetBy: count - 6)//把后边6个字符串截取掉不要
let resultString = original.substring(to: index)//截取后的字符串
let board = UIPasteboard.general//系统的剪切板
board.string = resultString//系统的剪切板保存结果字符串(如果是截取图片,就设置board.image = 你的图片)
这个时候你会发现,点击没有出现那个黑黑的,需要重写系统的这个属性的getter方法
override var canBecomeFirstResponder: Bool {
return true
}
到此,你以为就完结了?还有一个问题就是,你发现,第一次长按没有反应,第二次会出现,原因就是你没有把UIMenuController的对象设为全局的,在类文件开始的地方设置为属性就行了
var menu:UIMenuController!
另,这里实现的是copy,如果想实现cut,我也只是一个设想,只需要在点击item的那个方法里,把你label的text设置为空就可以了,变相的实现了剪切功能😄😄。
--------------分割线---------------
如果你不满足,想要一个可以实现选择范围,以及更多的功能,告诉你一个很厉害的方法,用textfield代替label来显示文本,长按,你会发现,功能很多哦。哈哈