概要
通常のUILabelは、フィールドの長押しでコピーができません。
UITextFieldのようにフィールドの長押しでコピーができるようにする方法です。
UILabelの文字を長押しでコピーする画面イメージ
以下の図のLabel1と書かれたUILabelを長押しした時に、Label1の文字列をコピーします。コピーした後に、UITextFieldなどにペーストできます。
実装方法
UILabelで長押しでコピーするために、以下のコードを、CopyUILabel.swiftとして追加します。このCopyUILabelを、storyboardで、長押しでコピーしたいUILabelのCustom Classで設定します。以下の図は、storyboardでUILabelにCopyUILabelを設定している図になります。
CopyUILabel.swift
class CopyUILabel: UILabel {
override init(frame: CGRect) {
super.init(frame: frame)
self.copyInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.copyInit()
}
func copyInit() {
self.isUserInteractionEnabled = true
self.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(CopyUILabel.showMenu(sender:))))
}
@objc func showMenu(sender:AnyObject?) {
self.becomeFirstResponder()
let contextMenu = UIMenuController.shared
if !contextMenu.isMenuVisible {
contextMenu.setTargetRect(self.bounds, in: self)
contextMenu.setMenuVisible(true, animated: true)
}
}
override func copy(_ sender: Any?) {
let pasteBoard = UIPasteboard.general
pasteBoard.string = text
let contextMenu = UIMenuController.shared
contextMenu.setMenuVisible(false, animated: true)
}
override var canBecomeFirstResponder: Bool {
return true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(UIResponderStandardEditActions.copy)
}
}
ソースコード
ここで説明したソースコードは、
[GitHub]
(https://github.com/hoge-san/sample-swift-copyUILabel)
で公開しています。
環境
- Xcode 10.2
- Swift 5
参考文献
- Apple公式マニュアル canPerformAction
- Apple公式マニュアル canBecomeFirstResponder