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

时间:2015-07-02 11:50:51

标签: ios objective-c uitableview uimenucontroller

我在我的UIMenuController中显示自定义tableview

enter image description here

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

但如果我显示UIMenuControllerUITableView 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
}

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 个答案:

答案 0 :(得分: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];

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

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