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