UIMenuController与UITableViewCell/UICollectionViewCell的结合

  1. 使用系统的api,无需添加长按手势,
  2. 不会隐藏键盘
  3. 可以控制响应的区域

以下是 UITableView 的demo

// ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // 或在cell中添加也可以
    UIMenuItem *menuItem = [[UIMenuItem alloc] initWithTitle:@"复制" action:@selector(copyItem:)];
    [[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObject:menuItem]];
}


- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if ([cell isKindOfClass:[BXSChatBaseTableViewCell class]]) {
        BXSChatBaseTableViewCell *bubbleCell = (BXSChatBaseTableViewCell *)cell;
        if (bubbleCell.canShowMenu) {
            [bubbleCell showMenu];
            return YES;
        }
    }
    return NO;
}

- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if ([cell isKindOfClass:[BXSChatBaseTableViewCell class]]) {
        BXSChatBaseTableViewCell *bubbleCell = (BXSChatBaseTableViewCell *)cell;
        return bubbleCell.canShowMenu;
    }
    return NO;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    // required
}


- (BOOL)canBecomeFirstResponder {
    return YES;
}

// Cell

- (BOOL)canShowMenu {
    // _bubbleView.frame 是Cell响应的范围,我这里是聊天的气泡
    return CGRectContainsPoint(_bubbleView.frame, self.touchAtPoint);
}

- (void)showMenu {
    NSNotificationCenter * __weak center = [NSNotificationCenter defaultCenter];
    id __block token = [center addObserverForName:UIMenuControllerWillShowMenuNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        [center removeObserver:token];
        UIMenuController *menu = [UIMenuController sharedMenuController];
        [menu setMenuVisible:NO animated:NO];

        if (self.canShowMenu) {
            [menu update];
            [menu setTargetRect:self.bubbleView.frame inView:self.contentView];
            [menu setMenuVisible:YES animated:YES];
        }
    }];
}

- (void)copyItem:(id)sender {
    UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
    [pasteboard setString:_model.plainText];
}

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    BOOL isCan = [super canPerformAction:action withSender:sender];
    if (action == @selector(copyItem:)) {
        isCan = YES;
    }
    return isCan;
}

//记录点击的位置,用来判断是否显示MenuController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [super touchesBegan:touches withEvent:event];
    _touchAtPoint = [touches.anyObject locationInView:self];
}

你可能感兴趣的:(UIMenuController与UITableViewCell/UICollectionViewCell的结合)