UIMenuController方法setTargetRect:inView:在UITableView中不起作用

S.J*_*S.J 11 objective-c uitableview uimenucontroller ios

我显示自定义UIMenuController在我tableview这样的

在此输入图像描述

但问题是它在中心显示我想要显示在其上面的label是橙色.为了在label我之上显示,[menu setTargetRect:CGRectMake(10, 10, 0, 0) inView:self.lbl];下面是整个代码.

但是,如果我显示UIMenuController没有UITableView setTargetRect工作正常.

为什么setTargetRect不合作UITableView

setTargetRect Doc说:

(a)此目标矩形(targetRect)通常是选区的边界矩形.UIMenuController将编辑菜单定位在此矩形上方; 如果那里没有足够的空间用于菜单,则将其定位在矩形下方.菜单指针根据需要放置在目标矩形的顶部或底部的中心.

(b)请注意,如果将目标矩形的宽度或高度设置为零,则UIMenuController会将目标区域视为用于定位的线或点(例如,插入插入符或单个点).

(c)设置后,目标矩形不跟踪视图; 如果视图移动(例如在滚动视图中发生),则必须相应地更新目标矩形.

我错过了什么?

MyViewController

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 5;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TheCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cid" forIndexPath:indexPath];

    cell.lbl.text = [NSString stringWithFormat:@"%ld", (long)indexPath.row];

    return cell;
}

- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
    return YES;
}

-(BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    return YES;
}

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    // required
}
Run Code Online (Sandbox Code Playgroud)

MyCustomCell

- (void)awakeFromNib {
    // Initialization code

    UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:@"Test" action:@selector(test:)];
    UIMenuController *menu = [UIMenuController sharedMenuController];
    [menu setMenuItems: @[testMenuItem]];

    [menu setTargetRect:CGRectMake(10, 10, 0, 0) inView:self.lbl];

    [menu update];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

-(BOOL) canPerformAction:(SEL)action withSender:(id)sender {
    return (action == @selector(copy:) || action == @selector(test:));
}

/// this methods will be called for the cell menu items
-(void) test: (id) sender {
    NSLog(@"test");
}

-(void) copy:(id)sender {
    UIMenuController *m = sender;
    NSLog(@"copy");
}
Run Code Online (Sandbox Code Playgroud)

Moi*_*had 15

1)首先,请在视图控制器的viewDidLoad方法中执行此操作.

 UIMenuItem *testMenuItem = [[UIMenuItem alloc] initWithTitle:@"Test"
    action:@selector(test:)];
[[UIMenuController sharedMenuController] setMenuItems: @[testMenuItem]];
 [[UIMenuController sharedMenuController] update];

 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillShow:) name:UIMenuControllerWillShowMenuNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillHide:) name:UIMenuControllerWillHideMenuNotification object:nil];
Run Code Online (Sandbox Code Playgroud)

2)然后,添加这两个方法.并设置menuFrame inView为您的单元格

-(void)menuControllerWillShow:(NSNotification *)notification{
 //Remove Will Show Notification to prevent
 // "menuControllerWillShow" function to be called multiple times
 [[NSNotificationCenter defaultCenter]removeObserver:self name:UIMenuControllerWillShowMenuNotification object:nil];

//Hide the Original Menu View
UIMenuController* menuController = [UIMenuController sharedMenuController];
CGSize size = menuController.menuFrame.size;
CGRect menuFrame;
menuFrame.origin.x = self.tableView.frame.origin.x;
menuFrame.size = size;
[menuController setMenuVisible:NO animated:NO];

//Modify its target rect and show it again to prevent glitchy appearance
   [menuController setTargetRect:menuFrame inView:cell];
    [menuController setMenuVisible:YES animated:YES];
}

 -(void)menuControllerWillHide:(NSNotification *)notification{
    //re-register menuControllerWillShow
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuControllerWillShow:)
 name:UIMenuControllerWillShowMenuNotification object:nil];
 }
Run Code Online (Sandbox Code Playgroud)

3)实现tableView Delegates并实现这些方法.

- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath {
    cell = (TableViewCell*)[tableView cellForRowAtIndexPath:indexPath];

    return YES;
}
-(BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    return NO;
}
- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender {
    // required
}
Run Code Online (Sandbox Code Playgroud)

4)使用设置单元格(子类化UITableViewCell)

 -(BOOL) canPerformAction:(SEL)action withSender:(id)sender {
    return (action == @selector(copy:) || action == @selector(test:)); } /// this methods will be called for the cell menu items
 -(void) test: (id) sender {
     NSLog(@"test"); }

 -(void) copy:(id)sender {
   NSLog(@"copy"); }
Run Code Online (Sandbox Code Playgroud)