2019 ...
保存任何输入:
public class SomeComplexCustomView: UIView {
@IBOutlet var oneOfYourLabels: UILabel!
... your other labels, boxes, etc
public func makeThatLabelCopyable() {
oneOfYourLabels.isUserInteractionEnabled = true
addGestureRecognizer(UITapGestureRecognizer(
target: self, action: #selector(self.copyMenu(sender:))))
addGestureRecognizer(UILongPressGestureRecognizer(
target: self, action: #selector(self.copyMenu(sender:))))
// or use oneOfYourLabels.addGesture... to touch just on that item
}
public override var canBecomeFirstResponder: Bool { return true }
@objc func copyMenu(sender: Any?) {
becomeFirstResponder()
UIMenuController.shared.setTargetRect(bounds, in: self)
// or any exact point you want the pointy box pointing to
UIMenuController.shared.setMenuVisible(true, animated: true)
}
override public func copy(_ sender: Any?) {
UIPasteboard.general.string = oneOfYourLabels.text
// or any exact text you wish
UIMenuController.shared.setMenuVisible(false, animated: true)
}
override public func canPerformAction(
_ action: Selector, withSender sender: Any?) -> Bool {
return (action == #selector(copy(_:)))
}
}
就这么简单!
一个微妙之处:
改善工程的一个细节:
注意我们开启了第一响应者:
public override var canBecomeFirstResponder: Bool { return true }
通常,在带有此类标签的给定屏幕上,您将拥有或不会拥有这样的可复制链接。
所以你很可能会有类似的东西:
var linkTurnedOnCurrently: Bool = false
func doShowThatLink( blah ) {
linkAvailableOnThisScreen = true
... the various code above ...
}
func doShowThatLink( blah ) {
linkAvailableOnThisScreen = false
... perhaps de-color the link, etc ...
}
因此,实际上不是这样:
public override var canBecomeFirstResponder: Bool { return true }
一定要这样做:
public override var canBecomeFirstResponder: Bool {
if linkTurnedOnCurrently { return true }
return super.canBecomeFirstResponder
}
(请注意,它不是类似于“return linkTurnedOnCurrently”。)