2011-12-05 9 views
7

Sto realizzando un'app per iphone simile all'app Messaggi che arriva sul telefono. Ho appena impostato la possibilità di copiare i messaggi tramite un UIMenuController, ma se la tastiera viene visualizzata e qualcuno tenta di copiare un messaggio, la tastiera si spegne (presumibilmente a causa del mio [cell becomeFirstResponder]; dove cell è la cella del messaggio da copiare).Mostrando UIMenuController perde tastiera

C'è un modo per mostrare il messaggio Copia senza perdere la tastiera?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: 
(NSIndexPath *)indexPath { 

    //...other cell setup stuff... 

    UILongPressGestureRecognizer *longPressGesture = 
    [[UILongPressGestureRecognizer alloc] 
     initWithTarget:self action:@selector(showCopyDialog:)]; 
    [cell addGestureRecognizer:longPressGesture]; 

    return cell; 
} 

- (void)showCopyDialog:(UILongPressGestureRecognizer *)gesture 
{ 
    if (gesture.state == UIGestureRecognizerStateBegan) 
    { 
     ConvoMessageCell *cell = (ConvoMessageCell *)[gesture view]; 
     NSIndexPath *indexPath = [self.tblConvo indexPathForCell:cell]; 

     UIMenuController *theMenu = [UIMenuController sharedMenuController]; 
     [cell becomeFirstResponder]; 
     [theMenu setTargetRect:CGRectMake(menuX, menuY, 100, 100) inView:cell]; 
     [theMenu setMenuVisible:YES animated:YES];   
    } 
} 

risposta

7

In iOS 5, è ora possibile utilizzare i metodi vista delegato tabella per mostrare il controller Menu:

- (BOOL) tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath 

- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender; 

- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender; 

Mostrando Controller Menu in questo modo non si dimetterà la tastiera.

Sono ancora curioso di questo anche se ho un'app che supporta il pre-iOS 5 che mi piacerebbe fare anche quello che dici (non rassegnare la tastiera quando appare il menu di copia).

+0

Questo potrebbe funzionare, ma il MenuController verrà posizionato direttamente nel centro orizzontale della cella. –

16

ho risolto questo dilemma sottoclasse UITextView per fornire un modo per ignorare il nextResponder e disattivare il built-in azioni (pasta), in questo modo:

@interface CustomResponderTextView : UITextView 

@property (nonatomic, weak) UIResponder *overrideNextResponder; 

@end 

@implementation CustomResponderTextView 

@synthesize overrideNextResponder; 

- (UIResponder *)nextResponder { 
    if (overrideNextResponder != nil) 
     return overrideNextResponder; 
    else 
     return [super nextResponder]; 
} 

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender { 
    if (overrideNextResponder != nil) 
     return NO; 
    else 
     return [super canPerformAction:action withSender:sender]; 
} 

@end 

Poi, nel vostro gestore di azioni gestuali, controlla se la vista testuale è già la prima a rispondere. In caso affermativo, farlo ignorare il prossimo risponditore; altrimenti la tastiera è probabilmente nascosta comunque e puoi semplicemente becomeFirstResponder. Avrete anche per ripristinare l'override quando il menu si nasconde:

if ([inputView isFirstResponder]) { 
    inputView.overrideNextResponder = self; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
     selector:@selector(menuDidHide:) 
     name:UIMenuControllerDidHideMenuNotification object:nil]; 
} else { 
    [self becomeFirstResponder]; 
} 

- (void)menuDidHide:(NSNotification*)notification { 

    inputView.overrideNextResponder = nil; 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
     name:UIMenuControllerDidHideMenuNotification object:nil]; 
} 

Utilizzando i metodi delegato vista tabella introdotte in iOS 5 (shouldShowMenuForRowAtIndexPath ecc) non era una soluzione per me come ho bisogno controllo sul posizionamento del menu (per impostazione predefinita è semplicemente centrato orizzontalmente sulla cella, ma sto visualizzando bolle di messaggi e desidero che il menu sia centrato sulla bolla effettiva).

+0

Ottima risposta, grazie! nessuna bibliografia per questo? – AmitP

+0

Questo funziona parzialmente. Il MenuController visualizzato appartiene a CustomResponderTextView e non alla cella. Qualche idea per risolverlo? –