UILabel有没有任何价值可供选择?

时间:2016-10-11 23:51:22

标签: ios swift uilabel

UILabel是否有任何可以设置的值以使其可选?

我有一个我想要选择的标签,(长按和复制btn显示)有点像Safari。

4 个答案:

答案 0 :(得分:3)

是的,您需要从应用于UILabel的长按手势实现UIMenuController。在NSHipster上有一篇关于此的优秀文章,但文章的要点如下。

创建UILabel的子类并实现以下方法:

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
}

然后在视图控制器中,您可以为标签添加长按手势:

let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: "handleLongPressGesture:")
label.addGestureRecognizer(gestureRecognizer)

用这种方法处理长按:

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()
     }}

注意:此代码直接来自NSHipster文章,我只是将其包含在此处以符合SO标准。

答案 1 :(得分:2)

自包含解决方案(Swift 5)

您可以改编@BJHSolutions和NSHipster的解决方案,以制作以下独立的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 {
            UIMenuController.shared.setTargetRect(recognizerView.frame, in: recognizerSuperview)
            UIMenuController.shared.setMenuVisible(true, animated:true)
            recognizerView.becomeFirstResponder()
        }
    }

}

答案 2 :(得分:0)

UILabel继承自UIView,因此您只需向标签添加长按手势识别器即可。请注意,您必须将isUserInteractionEnabled更改为true,因为标签的默认值为false。

    import UIKit

    class ViewController: UIViewController {
        let label = UILabel()

        override func viewDidLoad() {
            view.addSubview(label)
            label.text = "hello"
            label.translatesAutoresizingMaskIntoConstraints = false
            label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
            let longPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressLabel(longPressGestureRecognizer:)))
            label.addGestureRecognizer(longPressGestureRecognizer)
            label.isUserInteractionEnabled = true
        }

        @objc private func longPressLabel (longPressGestureRecognizer: UILongPressGestureRecognizer) {
            if longPressGestureRecognizer.state == .began {
                print("long press began")
            } else if longPressGestureRecognizer.state == .ended {
                print("long press ended")
            }

        }

    }

答案 3 :(得分:-1)

我已经实现了一个UILabel子类,它提供了所需的所有功能。请注意,如果您在界面构建器中使用它,则需要调整init方法。

/// A label that can be copied.
class CopyableLabel: UILabel
{
    // MARK: - Initialisation

    /// Creates a new label.
    init()
    {
        super.init(frame: .zero)

        let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(_:)))
        self.addGestureRecognizer(gestureRecognizer)

        self.isUserInteractionEnabled = true
    }

    required init?(coder aDecoder: NSCoder)
    {
        fatalError("init(coder:) has not been implemented")
    }

    // MARK: - Responder chain

    override var canBecomeFirstResponder: Bool
    {
        return true
    }

    // MARK: - Actions

    /// Method called when a long press is triggered.
    func handleLongPressGesture(_ gestuerRecognizer: UILongPressGestureRecognizer)
    {
        guard let superview = self.superview else { return }

        let menuController = UIMenuController.shared
        menuController.setTargetRect(self.frame, in: superview)
        menuController.setMenuVisible(true, animated:true)
        self.becomeFirstResponder()
    }

    override func copy(_ sender: Any?)
    {
        UIPasteboard.general.string = self.text
    }
}