2015-07-02 8 views
10

Ich Brauch UIMenuController in meinem tableview wie dieseUIMenuController Methode setTargetRect: INview: funktioniert nicht in UITableView

enter image description here

Anzeige aber Problem ist, dass es in der Mitte anzeigt ich es oben angezeigt werden soll von label welches orange ist. Für die Anzeige auf label habe ich dies [menu setTargetRect:CGRectMake(10, 10, 0, 0) inView:self.lbl]; unten ist der gesamte Code.

Aber wenn ich die UIMenuController ohne UITableViewsetTargetRect Anzeige funktioniert gut.

Warum funktioniert setTargetRect nicht mit UITableView?

setTargetRect Doc sagt:

(a) Das Zielrechteck (targetRect) ist in der Regel das Begrenzungsrechteck eine Auswahl. UIMenuController positioniert das Bearbeitungsmenü über diesem Rechteck ; Wenn dort nicht genügend Platz für das Menü ist, positioniert es es unterhalb des Rechtecks. Der Zeiger des Menüs befindet sich in der Mitte des oberen oder unteren Rands des Zielrechtecks ​​( ).

(b) Beachten Sie, dass die Breite oder Höhe des Zielrechteck bilden Null, UIMenuController behandelt den Zielbereich als eine Linie oder Punkt für Positionierung (zum Beispiel eine Einfügungs caret oder ein einzelner Punkt).

(c) Sobald das Zielrechteck gesetzt ist, verfolgt das Zielrechteck die Ansicht nicht; Wenn die Ansicht verschoben wird (wie dies in einer Bildlaufansicht der Fall wäre), müssen Sie das Zielrechteck entsprechend aktualisieren.

Was ich vermisse?

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

bin ich ziemlich sicher, da Sie eine benutzerdefinierte rect versuchen, zu verwenden, die Sie nicht für 'shouldShowMenuForRowAtIndexPath' zurückkehren sollen, die machen Sie die 'canPerformAction' und' performAction' Methoden ebenfalls überflüssig. –

+0

Meine einzige andere Sorge ist, dass das Label zum Zeitpunkt der Konfiguration des 'UIMenuControllers' nicht in die View-Hierarchie eingefügt worden wäre, was ein Problem sein könnte. Sie müssen den 'UIMenuController'-Konfigurationscode auf eine andere Delegate-Methode wie' tableView: willDisplayCell' oder vielleicht sogar auf die 'UIView'-Methode der Zelle [' didMoveToSuperview'] verschieben (https://developer.apple.com/ Bibliothek/ios/documentation/UIKit/Referenz/UIView_Class/index.html #/apple_ref/occ/instm/UIView/didMoveToSuperview) um sicherzustellen, dass die Zelle tatsächlich auf dem Bildschirm angezeigt wird, bevor Sie das benutzerdefinierte rect festlegen. –

+0

@SantaClaus Nö funktioniert nichts, mein Menü erscheint immer noch in der Mitte. –

Antwort

14

1) Zuerst tun Sie dies bitte in Ihrer viewDidLoad Methode des View-Controller.

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) Fügen Sie dann diese beiden Methoden hinzu. und setzen menuFrame inView für Ihr Handy

-(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) Implementieren Tableview Delegierten und diese Methoden implementieren.auch

- (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) Richten Sie die Zellen (Subklassen UITableViewCell) mit

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

Um 'Zelle' in' menuControllerWillShow' zu bekommen, hier ist Code: 'let menuOrigin = self.view.convertPoint (menuController.menuFrame.origin, toView: self.tableView) Lassen Sie indexPath = _chatTableView.indexPathForRowAtPoint (menuOrigin) lassen Zelle = _chatTableView.cellForRowAtIndexPath (indexPath!) '- Swift-Code – D4ttatraya

Verwandte Themen