Selectable UILabel contents
Asked Answered
W

3

5

I have a list of URL addresses in a iOS Label object. It does not appear that the user can select and copy an item from the list and paste it into their Safari browser on the iOS device. Is there a way to accomplish this?

Woodrum answered 3/3, 2013 at 18:7 Comment(0)
F
7

This feature is not there in UILabel.

You need to use UITextField or UITextView . Also do not forget to change its appearance and using

[... setEditable:NO];
Fervidor answered 3/3, 2013 at 18:12 Comment(1)
I don't think this is available for UITextField anymore? (on iOS 9.3)Jarrell
K
7

It is actually possible to do with an UILabel, only you'll have to do some subclassing.

End result: when your user long presses the label, he or she will see a copy-balloon.

Picture showing copy-balloon after long-pressing a label on iOS

Here are the steps to allow for making a label copy-able (as I can recall):

  1. subclass UILabel
  2. set userInteractionEnabled = YES
  3. override canBecomeFirstResponder and return true
  4. add a UILongPressGestureRecognizer
  5. become first responder & present UIMenuController

Swift 3:

let menu = UIMenuController.shared
if !menu.isMenuVisible {
    self.becomeFirstResponder()
    menu.setTargetRect(self.bounds, in: self)
    menu.setMenuVisible(true, animated: true)
}
  1. override canPerformAction to allow copy

Swift 3:

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        return action == #selector(UIResponderStandardEditActions.copy(_:))
}
  1. override copy method, UIPasteboard the text & hide UIMenuController

Swift 3:

        let menu = UIMenuController.shared          
        let labelText = self.text ?? self.attributedText?.string
        if let uLabelText = labelText {
            let clipBoard = UIPasteboard.general
            clipBoard.string = uText
        }

        menu.setMenuVisible(false, animated: true)
Kuhl answered 5/10, 2016 at 12:40 Comment(0)
P
1

Here is swift 5 version of JoriDor's solution;

class CopyableLabel: UILabel {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        sharedInit()
    }
    
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        sharedInit()
    }
    
    func sharedInit() {
        isUserInteractionEnabled = true
        addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(showMenu(sender:))))
    }
    
    @objc
    func showMenu(sender: AnyObject?) {
        becomeFirstResponder()
        let menu = UIMenuController.shared
        if !menu.isMenuVisible {
            menu.setTargetRect(bounds, in: self)
            menu.setMenuVisible(true, animated: true)
        }
    }
    
    override var canBecomeFirstResponder: Bool {
        return true
    }
    
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(UIResponderStandardEditActions.copy(_:)) {
            return true
        }
        return false
    }
    
    override func copy(_ sender: Any?) {
        let board = UIPasteboard.general
        board.string = text
        let menu = UIMenuController.shared
        menu.setMenuVisible(false, animated: true)
    }
    
}
Perishing answered 1/10, 2020 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.