我在 UITableViewCell
中有一个 UITextView
。我希望 UITextView
可以选择,但不能向其发送文本。当 Menu Controller
出现并且我想执行复制操作时,复制里面的所有文本,而不仅仅是一部分。
我想要像 Messenger 应用这样的东西:
目前我有:
提前致谢!
最佳答案
事实上这并不那么容易,因为在路上会出现一些奇怪的东西,但我设法创建了一个定制的。
步骤如下:
- 创建
UITextView
的子类 - 覆盖
canPerformAction: withSender:
用于过滤菜单的默认 Action 弹出。 - 配置
textView
以便无法编辑 或 选择。 - 编辑在菜单上提供操作和按钮的
UIMenuController
项 - 为每个
UIMenuItem
添加不同的选择器 ****(这是因为选择器的发送者不是UIMenuItem
,而是UIMenuController
这导致了另一件事。查看 here 了解更多信息。我为此提供了一个 gist)
代码
废话不多说,上代码:
EBCustomTextView.h
//
// EBCustomTextView.h
// TestProject
//
// Created by Erid Bardhaj on 3/8/16.
// Copyright © 2016 Erid Bardhaj. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, EBCustomTextViewMenuAction) {
EBCustomTextViewMenuActionCopy,
EBCustomTextViewMenuActionDefine,
EBCustomTextViewMenuActionRead
};
@class EBCustomTextView;
@protocol EBCustomTextViewMenuActionDelegate <NSObject>
- (void)customTextView:(EBCustomTextView *)textView didSelectMenuAction:(EBCustomTextViewMenuAction)action;
@end
@interface EBCustomTextView : UITextView
@property (weak, nonatomic) id<EBCustomTextViewMenuActionDelegate> menuActionDelegate;
@end
EBCustomTextView.m
//
// EBCustomTextView.m
// TestProject
//
// Created by Erid Bardhaj on 3/8/16.
// Copyright © 2016 Erid Bardhaj. All rights reserved.
//
#import "EBCustomTextView.h"
@implementation EBCustomTextView {
EBCustomTextViewMenuAction currentAction;
}
- (void)awakeFromNib {
[super awakeFromNib];
// Configure the textView
self.editable = NO;
self.selectable = NO;
}
#pragma mark - Datasource
- (NSArray *)items {
UIMenuItem *item = [[UIMenuItem alloc] initWithTitle:@"Copy" action:@selector(copyMenuItemPressed)];
UIMenuItem *item1 = [[UIMenuItem alloc] initWithTitle:@"Define" action:@selector(defineMenuItemPressed)];
UIMenuItem *item2 = [[UIMenuItem alloc] initWithTitle:@"Read" action:@selector(readMenuItemPressed)];
return @[item, item1, item2];
}
#pragma mark - Actions
- (void)copyMenuItemPressed {
if ([self.menuActionDelegate respondsToSelector:@selector(customTextView:didSelectMenuAction:)]) {
[self.menuActionDelegate customTextView:self didSelectMenuAction:EBCustomTextViewMenuActionCopy];
}
}
- (void)defineMenuItemPressed {
if ([self.menuActionDelegate respondsToSelector:@selector(customTextView:didSelectMenuAction:)]) {
[self.menuActionDelegate customTextView:self didSelectMenuAction:EBCustomTextViewMenuActionDefine];
}
}
- (void)readMenuItemPressed {
if ([self.menuActionDelegate respondsToSelector:@selector(customTextView:didSelectMenuAction:)]) {
[self.menuActionDelegate customTextView:self didSelectMenuAction:EBCustomTextViewMenuActionRead];
}
}
#pragma mark - Private
- (void)menuItemPressedAtIndex:(NSInteger)index {
currentAction = index;
if ([self.menuActionDelegate respondsToSelector:@selector(customTextView:didSelectMenuAction:)]) {
[self.menuActionDelegate customTextView:self didSelectMenuAction:currentAction];
}
}
#pragma mark Helpers
- (void)showMenuController {
UIMenuController *theMenu = [UIMenuController sharedMenuController];
theMenu.menuItems = [self items];
[theMenu update];
CGRect selectionRect = CGRectMake (0, 0, self.contentSize.width, self.contentSize.height);
[theMenu setTargetRect:selectionRect inView:self];
[theMenu setMenuVisible:(theMenu.isMenuVisible) ? NO : YES animated:YES];
}
#pragma mark - Overridings
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
// Filter any action for this textView except our custom ones
if (action == @selector(copyMenuItemPressed) || action == @selector(defineMenuItemPressed) || action == @selector(readMenuItemPressed)) {
return YES;
}
return NO;
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *theTouch = [touches anyObject];
if ([theTouch tapCount] == 1 && [self becomeFirstResponder]) {
[self showMenuController];
}
}
@end
实现
将您的 textView 的类设置为 EBCustomTextView
并符合 EBCustomTextViewMenuActionDelegate
界面
@interface ViewController () <EBCustomTextViewMenuActionDelegate>
viewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.textView.menuActionDelegate = self;
}
协议(protocol)一致性
#pragma mark - Delegation
#pragma mark EBCustomTextViewMenuActionDelegate
- (void)customTextView:(EBCustomTextView *)textView didSelectMenuAction:(EBCustomTextViewMenuAction)action {
switch (action) {
case EBCustomTextViewMenuActionCopy:
NSLog(@"Copy Action");
break;
case EBCustomTextViewMenuActionRead:
NSLog(@"Read Action");
break;
case EBCustomTextViewMenuActionDefine:
NSLog(@"Define Action");
break;
default:
break;
}
}
输出
享受 :)
关于ios - 选择里面没有选择文本的textView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35865135/