2015-07-02 34 views
10

我显示自定义UIMenuController在我tableview这样UIMenuController方法setTargetRect:inView:在UITableView的

enter image description here

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

但是,如果我显示UIMenuController没有UITableViewsetTargetRect工作正常。

为什么setTargetRect不适用于UITableView

setTargetRect文件表示:

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

我敢肯定,因为您要使用自定义的矩形,你应该为'shouldShowMenuForRowAtIndexPath'返回NO,这也将使'canPerformAction'和'performAction'方法也是不必要的。 –

+0

我唯一的担心是标签不会在配置'UIMenuController'时被插入视图层次结构中,这可能是一个问题。您可能需要将'UIMenuController'配置代码移动到不同的委托方法,比如'tableView:willDisplayCell',或者甚至可以在单元格的'UIView'方法['didMoveToSuperview'](https://developer.apple.com/在设置自定义矩形之前,确保单元格实际上位于屏幕上,以确保单元格可以在屏幕上显示。 –

+0

@SantaClaus没有任何工作,我的菜单仍然出现在中心。 –

回答

14

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

要'menuControllerWillShow'得到'cell',这里是代码:'让menuOrigin = self.view.convertPoint(menuController.menuFrame.origin,toView:self.tableView) 让indexPath = _chatTableView.indexPathForRowAtPoint(menuOrigin) 让细胞= _chatTableView.cellForRowAtIndexPath(indexPath!)' - Swift代码 – D4ttatraya