ios 在 UITextField 上启用复制和粘贴而不使其可编辑
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1920541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Enable copy and paste on UITextField without making it editable
提问by mrueg
I want the text in a UITextField
(or ideally, a UILabel
) to be non-editable, but at the same time give the user the ability to copy it to paste elsewhere.
我希望 a UITextField
(或理想情况下, a UILabel
)中的文本是不可编辑的,但同时让用户能够将其复制粘贴到其他地方。
回答by mrueg
My final solution was the following:
我的最终解决方案如下:
I created a subclass of UILabel (UITextField should work the same) that displays a UIMenuController after being tapped. CopyableLabel.m looks like this:
我创建了一个 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
回答by Shinigami
This question is pretty old and I'm surprised nobody has posted a solution without subclassing. The idea presented in @mrueg's answer is correct, but you shouldn't need to subclass anything. I just came across this problem and solved it like this:
这个问题已经很老了,我很惊讶没有人发布没有子类化的解决方案。@mrueg 的答案中提出的想法是正确的,但您不需要对任何内容进行子类化。我刚刚遇到这个问题并解决了这个问题:
In my view controller:
在我的视图控制器中:
- (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;
}
If you want to make this work for a UILabel
, it should work the same way with just adding a tap gesture recognizer instead of using the delegate method.
如果你想让UILabel
它为 a 工作,它应该以相同的方式工作,只需添加一个点击手势识别器而不是使用委托方法。
回答by Harris
This will do everything you need. Will be copyable. But not editable, and won't show a keyboard or a cursor.
这将完成您需要的一切。将是可复制的。但不可编辑,也不会显示键盘或光标。
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
}
}
回答by Alex Reynolds
Try UITextView
instead (I suspect it would work like a UILabel
for you). I tested this with its editable
property set to NO
, and double-tapping-to-copy worked for me.
试试吧UITextView
(我怀疑它会像UILabel
你一样工作)。我测试了它的editable
属性设置为NO
,双击复制对我有用。
回答by keeshux
Another solution is keeping the UITextField
enabled but programmatically preventing it from being edited. This is done with the following delegate method:
另一种解决方案是保持UITextField
启用但以编程方式阻止它被编辑。这是通过以下委托方法完成的:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
return NO;
}
I'm not aware of possible limitations though, currently suits my needs.
我不知道可能的限制,但目前适合我的需求。
回答by Veight Zhou
The following code saved me.
以下代码救了我。
textField.addTarget(target, action: "textFieldEditingDidEndAction:", forControlEvents: [.EditingDidEnd])
It seems Paste
is a single and complete edit event.
这似乎Paste
是一个单一且完整的编辑事件。