2015-07-02 9 views
10

ja wyświetlania niestandardowych UIMenuController w moim tableview jak tenUIMenuController metoda setTargetRect: INview: nie działa w UITableView

enter image description here

ale problemem jest to, że jest wyświetlany w centrum chcę wyświetlić go na górze label, który jest w kolorze pomarańczowym. Aby wyświetlić na górze label, zrobiłem ten [menu setTargetRect:CGRectMake(10, 10, 0, 0) inView:self.lbl]; poniżej jest cały kod.

Ale jeśli wyświetlam UIMenuController bez UITableViewsetTargetRect działa dobrze.

Dlaczego setTargetRect nie działa z UITableView?

setTargetRect Doc mówi:

(a) Ten prostokąt docelowy (targetRect) zwykle prostokąta opisanego z wyboru. UIMenuController ustawia menu edycji powyżej tego prostokąta ; jeśli nie ma wystarczająco dużo miejsca na menu, to ustawia je poniżej prostokąta. Wskaźnik menu znajduje się w środku górnej lub dolnej części docelowego prostokąta.

(b) Należy zauważyć, że jeśli to szerokość lub wysokość prostokąta docelowej zero UIMenuController traktuje docelowy obszar jak linia lub punkt dla położenia (na przykład, daszek wstawiania lub jeden punkt).

(c) Po ustawieniu docelowy prostokąt nie śledzi widoku; Jeśli przesunie się widok (taki jak w widoku przewijania), musisz odpowiednio zaktualizować docelowy prostokąt.

Czego mi brakuje?

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

jestem całkiem pewny, ponieważ próbujesz użyć niestandardowego rect, że należy powrócić do 'shouldShowMenuForRowAtIndexPath' NO, który będzie również sprawić, że metody 'canPerformAction' i' performAction' również nie będą potrzebne. –

+0

Moim jedynym zmartwieniem jest to, że etykieta nie zostałaby wstawiona do hierarchii widoków podczas konfigurowania 'UIMenuController', co może być problemem. Musisz "być może" przenieść kod konfiguracyjny 'UIMenuController' na inną metodę delegata, taką jak' tableView: willDisplayCell', a może nawet w komórce 'UIView' method [' didMoveToSuperview'] (https://developer.apple.com/ biblioteka/ios/documentation/UIKit/Reference/UIView_Class/index.html # // apple_ref/occ/instm/UIView/didMoveToSuperview), aby upewnić się, że komórka rzeczywiście znajduje się na ekranie przed ustawieniem niestandardowego prostokąta. –

+0

@SantaClaus Nie, nic nie działa, moje menu wciąż pojawia się w środku. –

Odpowiedz

14

1) Po pierwsze, należy to zrobić w viewDidLoad metody Państwa zdanie kontrolera.

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) Następnie dodaj te dwie metody. i ustawić menuFrame inView do komórki

-(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) realizują Tableview delegatów i wdrożenia tych metod.

- (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) Konfiguracja komórki (instacji UITableViewCell) z

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

Aby dostać 'cell' w' menuControllerWillShow', oto kod: 'niech menuOrigin = self.view.convertPoint (menuController.menuFrame.origin, toview: self.tableView) niech indexPath = _chatTableView.indexPathForRowAtPoint (menuOrigin) niech komórka = _chatTableView.cellForRowAtIndexPath (indexPath!) '- Kod Swift – D4ttatraya

Powiązane problemy