在开发过程中,有时候我们需要实现一些长按保存、删除、复制等一系列操作,UIMenuCOntroller
这个菜单可以帮我们实现这些功能,通常和UIResponderStandardEditActions
搭配使用。
UIResponderStandardEditActions
是UIResponder
中定义的一个协议,方法有
- (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];
}
}