UIMenuController和UIResponderStandardEditActions分析

在开发过程中,有时候我们需要实现一些长按保存、删除、复制等一系列操作,UIMenuCOntroller这个菜单可以帮我们实现这些功能,通常和UIResponderStandardEditActions搭配使用。

UIResponderStandardEditActionsUIResponder中定义的一个协议,方法有

- (void)cut:(nullable id)sender NS_AVAILABLE_IOS(3_0);//剪切
- (void)copy:(nullable id)sender NS_AVAILABLE_IOS(3_0);//复制
- (void)paste:(nullable id)sender NS_AVAILABLE_IOS(3_0);//粘贴
- (void)select:(nullable id)sender NS_AVAILABLE_IOS(3_0);//选择
- (void)selectAll:(nullable id)sender NS_AVAILABLE_IOS(3_0);//全选
- (void)delete:(nullable id)sender NS_AVAILABLE_IOS(3_2);//删除
- (void)makeTextWritingDirectionLeftToRight:(nullable id)sender NS_AVAILABLE_IOS(5_0);//左对齐
- (void)makeTextWritingDirectionRightToLeft:(nullable id)sender NS_AVAILABLE_IOS(5_0);//右对齐
- (void)toggleBoldface:(nullable id)sender NS_AVAILABLE_IOS(6_0);//粗体
- (void)toggleItalics:(nullable id)sender NS_AVAILABLE_IOS(6_0);//斜体
- (void)toggleUnderline:(nullable id)sender NS_AVAILABLE_IOS(6_0);//下划线 
//
- (void)increaseSize:(nullable id)sender NS_AVAILABLE_IOS(7_0);//字号增大
- (void)decreaseSize:(nullable id)sender NS_AVAILABLE_IOS(7_0);//字号减小

通常和UIMenuController搭配使用

UIMenuController继承自NSObject方法有

//  单例获取对象
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) UIMenuController *sharedMenuController;
#else
+ (UIMenuController *)sharedMenuController;
#endif
//  显示菜单
@property(nonatomic,getter=isMenuVisible) BOOL menuVisible;     
// default is NO 
- (void)setMenuVisible:(BOOL)menuVisible animated:(BOOL)animated;
//  设置菜单相对于操作控件的位置  和 父视图,注意这里设置之后菜单并不会跟随view的移动而移动,需要手动更新
- (void)setTargetRect:(CGRect)targetRect inView:(UIView *)targetView;
//  菜单箭头的位置
@property(nonatomic) UIMenuControllerArrowDirection arrowDirection NS_AVAILABLE_IOS(3_2); // default is UIMenuControllerArrowDefault
//  菜单选项        
@property(nullable, nonatomic,copy) NSArray<UIMenuItem *> *menuItems NS_AVAILABLE_IOS(3_2); // default is nil. these are in addition to the standard items
//  更新菜单
- (void)update; 
//  只读,获取frame
@property(nonatomic,readonly) CGRect menuFrame

//  菜单状态的通知
UIKIT_EXTERN NSNotificationName const 
UIMenuControllerWillShowMenuNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const 
UIMenuControllerDidShowMenuNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIMenuControllerWillHideMenuNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIMenuControllerDidHideMenuNotification __TVOS_PROHIBITED;
UIKIT_EXTERN NSNotificationName const UIMenuControllerMenuFrameDidChangeNotification __TVOS_PROHIBITED;

//  菜单选项,可以在这里更改菜单选项的文字和要执行的方法
NS_CLASS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED @interface UIMenuItem : NSObject 

- (instancetype)initWithTitle:(NSString *)title action:(SEL)action NS_DESIGNATED_INITIALIZER;

@property(nonatomic,copy) NSString *title;
@property(nonatomic)      SEL       action;

@end

在使用时要注意:

//  首先要添加手势,比如我加的长按手势
- (instancetype)initWithFrame:(CGRect)frame {
if(self = [super initWithFrame:frame]) {
    [self attachTapHandle];
}
return self;
}

- (void)awakeFromNib {
[super awakeFromNib];
[self attachTapHandle];
}

// 添加长按手势
- (void)attachTapHandle {
self.userInteractionEnabled = true;
UILongPressGestureRecognizer * longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)];
[self addGestureRecognizer:longPress];
}

// 不设置这个方法,会导致无法调出menu菜单
- (BOOL)canBecomeFirstResponder {
return true;
}
    
// 再此方法中判断允许的方法,否则菜单项不弹出
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
//    UIResponder
if(action == @selector(paste:)      ||
   action == @selector(copy:)       ||
   action == @selector(cut:)        ||
   action == @selector(delete:)     ||
   action == @selector(changeBackgroundColor:)) {
    return YES;
}
return NO;
}

//  可以在此方法中改变菜单文字或者设置自己的方法
- (void)handleTap:(UILongPressGestureRecognizer *)longPress {
if (longPress.state == UIGestureRecognizerStateBegan) {
    [self becomeFirstResponder];
    [[UIMenuController sharedMenuController] setTargetRect:self.frame inView:self.superview];
//        [UIMenuController sharedMenuController].arrowDirection = UIMenuControllerArrowRight;
    UIMenuItem * item = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copy:)];
    UIMenuItem * item1 = [[UIMenuItem alloc] initWithTitle:@"改变背景色" action:@selector(changeBackgroundColor:)];
    [[UIMenuController sharedMenuController] setMenuItems:@[item, item1]];
    [[UIMenuController sharedMenuController] setMenuVisible:YES animated:YES];
    [[UIMenuController sharedMenuController] update];
}
}

详细Demo

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容