-
Можем ли мы включить меню вырезания скопированной копии для
UILabel
, как и дляUITextField
? -
Если нет, и мне нужно преобразовать мой
UILabel
вUITextField
, как я могу включить меню вырезания скопированной копии и не разрешать изменение содержимого?
Показать меню вырезания iPhone на панели UILabel
Ответ 1
Я получил копию & вставляя меню, работающее на UILabel
, мне просто нужно было вернуть YES
для canBecomeFirstResponder
, а затем вызвать [label becomeFirstResponder]
, когда указанный ярлык должен был появиться на экране. Что касается возврата YES
из canBecomeFirstResponder
, вы можете создать собственный подкласс или патч UILabel
с помощью категории:
@implementation UILabel (Clipboard)
- (BOOL) canBecomeFirstResponder
{
return YES;
}
@end
Решение категории кажется немного хакерским, но если вы знаете, что вы делаете, это может быть проще, чем подклассификация. Я также разместил образец проекта на GitHub, который показывает, как отображать простое меню на UILabel
.
Ответ 2
Для Swift 3 и Swift 4 вы должны реализовать этот класс:
import UIKit
class CopyableLabel: UILabel {
override init(frame: CGRect) {
super.init(frame: frame)
self.sharedInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.sharedInit()
}
func sharedInit() {
self.isUserInteractionEnabled = true
self.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(self.showMenu)))
}
@objc func showMenu(sender: AnyObject?) {
self.becomeFirstResponder()
let menu = UIMenuController.shared
if !menu.isMenuVisible {
menu.setTargetRect(bounds, in: self)
menu.setMenuVisible(true, animated: true)
}
}
override func copy(_ sender: Any?) {
let board = UIPasteboard.general
board.string = text
let menu = UIMenuController.shared
menu.setMenuVisible(false, animated: true)
}
override var canBecomeFirstResponder: Bool {
return true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(UIResponderStandardEditActions.copy)
}
}
В вашей раскадровке просто UILabel
подкласс UILabel
с классом CopyableLabel
Ответ 3
образец проекта на github из-за ответа @zoul - это путь. На момент написания этого проекта этот проект фактически ничего не помещал в буфер обмена (картон). вот как:
Измените реализацию @zoul этого метода на:
- (void) copy:(id)sender {
UIPasteboard *pboard = [UIPasteboard generalPasteboard];
pboard.string = self.text;
}
Ответ 4
Swift 4 ☻ Xcode 9.2. Используя UIMenuController
мы можем это сделать.
Я создал IBDesignable
Custom UILabel
класс, который вы можете назначить непосредственно на раскадровке
@IBDesignable
class TapAndCopyLabel: UILabel {
override func awakeFromNib() {
super.awakeFromNib()
//1.Here i am Adding UILongPressGestureRecognizer by which copy popup will Appears
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressGesture(_:)))
self.addGestureRecognizer(gestureRecognizer)
self.isUserInteractionEnabled = true
}
// MARK: - UIGestureRecognizer
@objc func handleLongPressGesture(_ recognizer: UIGestureRecognizer) {
guard recognizer.state == .recognized else { return }
if let recognizerView = recognizer.view,
let recognizerSuperView = recognizerView.superview, recognizerView.becomeFirstResponder()
{
let menuController = UIMenuController.shared
menuController.setTargetRect(recognizerView.frame, in: recognizerSuperView)
menuController.setMenuVisible(true, animated:true)
}
}
//2.Returns a Boolean value indicating whether this object can become the first responder
override var canBecomeFirstResponder: Bool {
return true
}
//3.Here we are enabling copy action
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return (action == #selector(UIResponderStandardEditActions.copy(_:)))
}
// MARK: - UIResponderStandardEditActions
override func copy(_ sender: Any?) {
//4.copy current Text to the paste board
UIPasteboard.general.string = text
}
}
Выход:
Ответ 5
Я создал подкласс UILabel с открытым исходным кодом, который показывает UIMenuController с опцией "Копировать" при длительном нажатии:
HTCopyableLabel на GitHub
Ответ 6
Я разработал пример проекта zoul и добавил поддержку ARC (и пару других функций), если кому-то все еще интересно:
https://github.com/zhbrass/UILabel-Clipboard
CopyLabel.h/.m должен быть тем, что вы ищете
Ответ 7
Переопределите метод UITextField
instance textFieldShouldBeginEditing
и установите его для возврата NO
, чтобы отключить редактирование.
Посмотрите UITextFieldDelegate
для более подробной информации.
Ответ 8
Если у вас есть многострочный текст, вы должны использовать UITextView
Установите делегата:
func textView(_ textView: UITextView,
shouldChangeTextIn range: NSRange,
replacementText text: String) -> Bool {
return false
}
И это должно работать волшебно :)
Ответ 9
@benvolioT github project - очень хороший пример для копирования. А для пасты настройте canPerformAction:withSender:
.
Подробнее см. Пример CopyPasteTile.
Ответ 10
В Swift 5.0 и Xcode 10.2
Добавьте опцию копирования в вашу UILabel прямо в вашем ViewController.
//This is your UILabel
@IBOutlet weak var lbl: UILabel!
//In your viewDidLoad()
self.lbl.isUserInteractionEnabled = true
let longPress = UILongPressGestureRecognizer.init(target: self, action: #selector((longPressFunctin(_:))))
self.lbl.addGestureRecognizer(longPress)
//Write these all functions outside the viewDidLoad()
@objc func longPressFunctin(_ gestureRecognizer: UILongPressGestureRecognizer) {
lbl.becomeFirstResponder()
let menu = UIMenuController.shared
if !menu.isMenuVisible {
menu.setTargetRect(CGRect(x: self.lbl.center.x, y: self.lbl.center.y, width: 0.0, height: 0.0), in: view)
menu.setMenuVisible(true, animated: true)
}
}
override func copy(_ sender: Any?) {
let board = UIPasteboard.general
board.string = lbl.text
}
override var canBecomeFirstResponder: Bool {
return true
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(copy(_:))
}
Ответ 11
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(_:)))
}
}
Это так просто!