iOS基础扩展iOS学习UIview子类

iOS-UIMenuController的使用

2016-06-30  本文已影响2478人  xiaoaihhh

第一次使用UIMenuController,遇见一些问题,记录如下。

概念

UIMenuController即菜单控制器,是一个单例对象,用来复制,粘贴,删除等内容的操作。

使用步骤

通过下面三部完成UIMenuController的使用,缺一不可

使用菜单

假设点击控制器的view显示菜单,那么在控制的touchesBegan方法中按照上面说的三步设置UIMenuController

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setTargetRect:CGRectMake(100, 300, 200, 20) inView:self.view];
    menu.menuVisible = YES;
}

此时我们运行程序,点击控制的view并没有弹出菜单,原因是:

1.控制器或者UIView能够成为first responder ,需要实现下面方法

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

2.在显示菜单时需要设置为first responder ,在touchesBegan中添加[self becomeFirstResponder];

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self becomeFirstResponder]; //设置为第一响应者 
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setTargetRect:CGRectMake(100, 300, 200, 20) inView:self.view];
    menu.menuVisible = YES;
}

3.并且需要实现UIResponder的canPerformAction:withSender:方法,该方法与编辑菜单相关,与返回YES的方法关联的菜单将显示出来。

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    if (action == @selector(paste:))
    {
        return YES;
    } else if (action == @selector(cut:))
    {
        return YES;
    }
    else{
        return NO;
    }
}

其中paste:cut:方法都定义在UIResponderStandardEditActions协议,都是与菜单相关的。
由于只有paste:cut:方法能够响应,因此只显示cut和paste两个菜单,显示效果如下

如果直接返回YES,那么所有菜单都会显示,如下图。

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
     return YES;
}

说明:如果canPerformAction:withSender: 的first responder没有处理事件,会顺着响应链向上抛。

使用自定义菜单

可以通过UIMenuItem来自定义菜单,需要设置菜单的显示内容以及点击菜单的后的处理方法。然后将自定义的UIMenuItem添加到UIMenuController的menuItems(一个数组)属性中。其它使用过程与上面讲解的使用菜单的过程一样。 具体使用见下面例子,

添加自定义菜单

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self becomeFirstResponder]; //成为第一响应者 
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setTargetRect:CGRectMake(100, 300, 200, 20) inView:self.view];
  // 定义两个菜单a和b
    UIMenuItem *a = [[UIMenuItem alloc] initWithTitle:@"a"
                        action:@selector(aAction)];
    UIMenuItem *b = [[UIMenuItem alloc] initWithTitle:@"b"
                             action:@selector(bAction)];
 // 自定义菜单添加到菜单栏中
    menu.menuItems = @[like,writeBack,report];
    menu.menuVisible = YES;
}

实现aActionbAction方法

- (void)aAction{
    NSLog(@"--aAction--")
}

- (void)bAction{
    NSLog(@"--bAction--")
}

控制器或者UIView能够成为first responder

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

实现canPerformAction:withSender:方法

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    // 显示一个系统的paste以及自定义的a,b菜单
    if (action == @selector(paste:) || 
    action == @selector(aAction) ||
    action == @selector(bAction))
    {
        return YES;
    } 
    else{
        return NO;
    }
}

运行程序,显效果如下

说明:系统的菜单会显示在自定义菜单之前。

其它说明

如下图红色箭头所指所示,菜单箭头指针默认向下,可以通过设置arrowDirection属性改变其方向,支持上下左右四个方法。

箭头指针最下面的点即- (void)setTargetRect:(CGRect)targetRect inView:(UIView *)targetView方法中targetRect说设置的位置,具体指向的点见使用步骤说解释。

参考资料

apple官方文档
关于UIMenuController的用法例子

上一篇下一篇

猜你喜欢

热点阅读