事实上,这并不容易,因为在路上会出现一些奇怪的东西,但我设法创建了一个自定义的。
步骤如下:
- 创建
UITextView 的子类
- 覆盖
canPerformAction:
withSender:以过滤菜单的默认操作
弹出。
- 配置
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;
}
协议一致性
#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;
}
}
输出
享受:)