Этот вопрос довольно старый, и я удивлен, что никто не опубликовал решение без подклассов. Идея, представленная в ответе @ 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
, оно должно работать так же, просто добавив распознаватель жестов касания вместо использования метода делегата.