ios 在UITextField上启用复制和粘贴,但不使其可编辑

jhkqcmku  于 2023-06-07  发布在  iOS
关注(0)|答案(7)|浏览(561)

我希望UITextField(或理想情况下,UILabel)中的文本是不可编辑的,但同时给予用户能够复制它粘贴到其他地方。

pkbketx9

pkbketx91#

我的最终解决方案如下:
我创建了UILabel的一个子类(UITextField应该也是一样的),它在被点击后显示一个UIMenuController。CopyableLabel.m看起来像这样:

@implementation CopyableLabel

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if(action == @selector(copy:)) {
    return YES;
}
else {
    return [super canPerformAction:action withSender:sender];
}
}

- (BOOL)canBecomeFirstResponder {
return YES;
}

- (BOOL)becomeFirstResponder {
if([super becomeFirstResponder]) {
    self.highlighted = YES;
    return YES;
}
return NO;
}

- (void)copy:(id)sender {
UIPasteboard *board = [UIPasteboard generalPasteboard];
[board setString:self.text];
self.highlighted = NO;
[self resignFirstResponder];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
if([self isFirstResponder]) {
    self.highlighted = NO;
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setMenuVisible:NO animated:YES];
    [menu update];
    [self resignFirstResponder];
}
else if([self becomeFirstResponder]) {
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setTargetRect:self.bounds inView:self];
    [menu setMenuVisible:YES animated:YES];
}
}

@end
hzbexzde

hzbexzde2#

这个问题已经很老了,我很惊讶没有人在没有子类化的情况下发布解决方案。@mrueg的答案中提出的想法是正确的,但您不需要子类化任何东西。我就是碰到了这个问题,就这样解决了:
在我的视图控制器中:

- (void)viewDidLoad {
    self.textField.delegate = self;
    self.textField.text = @"Copyable, non-editable string.";
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (void)copyTextFieldContent:(id)sender {
    UIPasteboard* pb = [UIPasteboard generalPasteboard];
    pb.string = self.textField.text;
}

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    // UIKit changes the first responder after this method, so we need to show the copy menu after this method returns.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
         [self becomeFirstResponder];
         UIMenuController* menuController = [UIMenuController sharedMenuController];
         UIMenuItem* copyItem = [[UIMenuItem alloc] initWithTitle:@"Copy"
                                                           action:@selector(copyTextFieldContent:)];
         menuController.menuItems = @[copyItem];
         CGRect selectionRect = textField.frame;
         [menuController setTargetRect:selectionRect inView:self.view];
         [menuController setMenuVisible:YES animated:YES];
     });
     return NO;
}

如果你想让这个方法在UILabel上工作,它应该以同样的方式工作,只需要添加一个点击手势识别器,而不是使用delegate方法。

brc7rcf0

brc7rcf03#

这会做你需要的一切。会被复制。但不可编辑,并且不会显示键盘或光标。

class ViewController: UIViewController {

    @IBOutlet weak var copyableUneditableTextfield: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        copyableUneditableTextfield.delegate = self
        copyableUneditableTextfield.inputView = UIView()   //prevents keyboard     
        copyableUneditableTextfield.tintColor = .clear     //prevents cursor
        copyableUneditableTextfield.text = "Some Text You Want User To Copy But Not Edit"

    }

}

extension ViewController: UITextFieldDelegate {

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        return false //prevents editing
    }

}
uubf1zoe

uubf1zoe4#

尝试使用UITextView(我怀疑它的工作方式与UILabel类似)。我测试了它的editable属性设置为NO,双击复制对我来说很有效。

vc9ivgsu

vc9ivgsu5#

另一种解决方案是保持UITextField处于启用状态,但以编程方式阻止其被编辑。这是通过以下delegate方法完成的:

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    return NO;
}

我不知道可能的限制,虽然,目前适合我的需要。

ar5n3qh5

ar5n3qh56#

如何使用UITextView?

yourTextView.isEditable = false

您可以复制但不能编辑。

o2g1uqev

o2g1uqev7#

下面的代码救了我。

textField.addTarget(target, action: "textFieldEditingDidEndAction:", forControlEvents: [.EditingDidEnd])

Paste似乎是一个单一的完整的编辑事件。

相关问题