启用UITextField上的复制和粘贴操作,而不使其可编辑

我希望UITextField (或理想情况下, UILabel )中的文本是不可编辑的 ,但同时使用户能够将其复制到其他位置。

我的最终解决scheme如下:

我创build了一个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 

这个问题是相当古老的,我很惊讶没有人发布了一个没有子类化的解决scheme。 在@ 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 ,它应该以相同的方式添加一个轻拍手势识别器,而不是使用委托方法。

尝试UITextView而不是(我怀疑它会像你的UILabel工作)。 我testing了它的editable属性设置为NO ,并且双击 – 复制为我工作。

另一个解决scheme是保持启用UITextField但以编程方式阻止它被编辑。 这是用下面的委托方法完成的:

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

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

以下代码保存了我。

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

看来Paste是一个单一的和完整的编辑事件。

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

 class ViewController: UIViewController { @IBOutlet weak var copyableUneditableTextfield: UITextField! override func viewDidLoad() { super.viewDidLoad() 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 } }