2015-07-02 10 views
10

io sono la visualizzazione personalizzata UIMenuController nel mio tableview come questometodo UIMenuController setTargetRect: INview: non funziona in UITableView

enter image description here

ma problema è che si sta visualizzando nel centro voglio visualizzare in cima label che è di colore arancione. Per la visualizzazione sopra label ho fatto questo [menu setTargetRect:CGRectMake(10, 10, 0, 0) inView:self.lbl]; di seguito è l'intero codice.

Ma se visualizzo lo UIMenuController senza UITableViewsetTargetRect funziona correttamente.

Perché setTargetRect non funziona con UITableView?

setTargetRect Doc dice:

(a) Questo rettangolo di destinazione (targetRect) è solitamente il rettangolo di delimitazione di una selezione. UIMenuController posiziona il menu di modifica sopra questo rettangolo ; se non c'è abbastanza spazio per il menu, lo lo posiziona sotto il rettangolo. Il puntatore del menu è posizionato al centro nella parte superiore o inferiore del rettangolo di destinazione, a seconda dei casi.

(b) Si noti che se si effettua la larghezza o altezza del rettangolo bersaglio zero UIMenuController considera l'area di destinazione come una linea o punto per posizionamento (ad esempio, un punto di inserimento o un singolo punto).

(c) Una volta impostato, il rettangolo di destinazione non traccia la vista; se la vista si sposta (come accade in una vista di scorrimento), è necessario aggiornare di conseguenza il rettangolo di destinazione .

Cosa mi manca?

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

sono abbastanza sicuro dal momento che si sta tentando di utilizzare un rettangolo personalizzato che si dovrebbe tornare NO per 'shouldShowMenuForRowAtIndexPath', che sarà anche anche i metodi 'canPerformAction' e' performAction' sono superflui. –

+0

L'unica mia preoccupazione è che l'etichetta non sarebbe stata inserita nella gerarchia della vista nel momento in cui si configura 'UIMenuController', che potrebbe essere un problema. È necessario spostare il codice di configurazione 'UIMenuController' su un diverso metodo di delegato come' tableView: willDisplayCell', o forse anche nel metodo 'UIView' della cella [' didMoveToSuperview'] (https://developer.apple.com/ libreria/ios/documentazione/UIKit/Riferimento/UIView_Class/index.html # // apple_ref/occ/instm/UIView/didMoveToSuperview) per assicurarsi che la cella sia effettivamente sullo schermo prima di impostare il rect personalizzato. –

+0

@SantaClaus Niente funziona, il mio menu appare ancora al centro. –

risposta

14

1) In primo luogo, si prega di fare questo in modo viewDidLoad del controller della vista.

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) Quindi, aggiungere questi due metodi. e impostare menuFrame inView per il tuo cellulare

-(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) Implementare tableView delegati e implementare questi metodi.

- (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) installazione delle celle (sottoclasse UITableViewCell) con

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

Per ottenere 'cell' in' menuControllerWillShow', ecco il codice: 'menuOrigin = self.view.convertPoint (menuController.menuFrame.origin, toView: self.tableView) let indexPath = _chatTableView.indexPathForRowAtPoint (menuOrigin) let cell = _chatTableView.cellForRowAtIndexPath (indexPath!) '- Codice Swift – D4ttatraya