Does UILabel
have any value that can be set in order to make it selectable?
I have a label that I want to be selectable, (long press and a copy btn shows up) kinda like in Safari.
The steps are as follows: Create a subclass of UILabel which you will use anywhere you want your label text to be selectable. Add a long press gesture recogniser. Upon long press, present the UIMenuController shared instance with the menu items you need, in this case, Copy and Speak.
With a UILabel you can check for truncation by calculating the size of the text within the label and comparing that with the bounds of the label itself. If the text extends beyond the bounds then it's being displayed as truncated.
A view that displays one or more lines of informational text.
You can adapt the solution from @BJHSolutions and NSHipster to make the following self-contained SelectableLabel
:
import UIKit
/// Label that allows selection with long-press gesture, e.g. for copy-paste.
class SelectableLabel: UILabel {
override func awakeFromNib() {
super.awakeFromNib()
isUserInteractionEnabled = true
addGestureRecognizer(
UILongPressGestureRecognizer(
target: self,
action: #selector(handleLongPress(_:))
)
)
}
override var canBecomeFirstResponder: Bool {
return true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(copy(_:))
}
// MARK: - UIResponderStandardEditActions
override func copy(_ sender: Any?) {
UIPasteboard.general.string = text
}
// MARK: - Long-press Handler
@objc func handleLongPress(_ recognizer: UIGestureRecognizer) {
if recognizer.state == .began,
let recognizerView = recognizer.view,
let recognizerSuperview = recognizerView.superview {
recognizerView.becomeFirstResponder()
UIMenuController.shared.setTargetRect(recognizerView.frame, in: recognizerSuperview)
UIMenuController.shared.setMenuVisible(true, animated:true)
}
}
}
Yes, you need to implement a UIMenuController from a long press gesture applied to your UILabel. There is an excellent article about this on NSHipster, but the gist of the article is the following.
Create a subclass of UILabel and implement the following methods:
override func canBecomeFirstResponder() -> Bool {
return true
}
override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
return (action == "copy:")
}
// MARK: - UIResponderStandardEditActions
override func copy(sender: AnyObject?) {
UIPasteboard.generalPasteboard().string = text
}
Then in your view controller, you can add a long press gesture to your label:
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPressGesture:")
label.addGestureRecognizer(gestureRecognizer)
and handle the long press with this method:
func handleLongPressGesture(recognizer: UIGestureRecognizer) {
if let recognizerView = recognizer.view,
recognizerSuperView = recognizerView.superview
{
let menuController = UIMenuController.sharedMenuController()
menuController.setTargetRect(recognizerView.frame, inView: recognizerSuperView)
menuController.setMenuVisible(true, animated:true)
recognizerView.becomeFirstResponder()
}}
NOTE: This code is taken directly from the NSHipster article, I am just including it here for SO compliance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With