2011-12-05 50 views
7

我正在製作一個類似於手機上的Messages應用程序的iphone應用程序。我只是設置了通過UIMenuController複製郵件的功能,但是如果鍵盤顯示並且有人試圖複製郵件,鍵盤就會消失(大概是因爲我的[cell becomeFirstResponder];,其中cell是被複制的郵件單元格)。顯示UIMenuController丟失鍵盤

有沒有辦法顯示覆制信息而不會丟失鍵盤?

- (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];   
    } 
} 

回答

7

在iOS 5中,您現在可以使用表視圖委託方法來顯示菜單控制器:

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

顯示菜單控制器以這種方式不會辭職的鍵盤。

我仍然對此感到好奇,因爲我有一個應用程序支持iOS 5以前的版本,我希望按照您所說的操作(當複製菜單出現時不會退出鍵盤)。

+0

這可能工作,但MenuController將被放置在單元格的水平中心。 –

16

我通過繼承的UITextView提供一種方式來覆蓋nextResponder和禁用內置的動作(粘貼)解決了這個難題,就像這樣:

@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 

然後,在你手勢動作處理程序,檢查文本視圖是否已經是第一響應者。如果是這樣,是否覆蓋下一個響應者;否則鍵盤可能隱藏無論如何,你可以簡單地becomeFirstResponder。您還可以重置覆蓋當菜單隱藏:

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]; 
} 

使用iOS 5中(shouldShowMenuForRowAtIndexPath等)推出的表視圖委託方法是不是一個解決方案,我,我需要控制定位(默認情況下,它只是簡單地在單元格中水平居中,但是我正在顯示消息氣泡,並希望菜單居中在實際氣泡上)。

+0

很好的答案,謝謝!任何參考書目? – AmitP

+0

這部分工作。顯示的MenuController屬於CustomResponderTextView而不屬於單元格。任何想法來解決這個問題? –