UIMenuController方法setTargetRect:inView:不能在UITableView中工作

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

在这里输入图像说明

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

但是,如果我显示没有UITableViewUIMenuController setTargetRect工作正常。

为什么setTargetRect不能使用UITableView

setTargetRect Doc说:

(a)这个目标矩形(targetRect)通常是select的边界矩形。 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 } 

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"); } 

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]; 

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]; } 

3)实现tableView委托并实现这些方法。

 - (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 } 

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"); }