UIMenuController的canPerformAction方法调用按钮点击

时间:2015-10-14 11:11:18

标签: ios objective-c uitableview uimenucontroller

我有一个消息视图,用户可以在其中查看对话并输入&发信息。用户长按消息时显示菜单(上下文菜单的种类)。我已经分别使用TableView和Button进行聊天记录和发送消息按钮。 我的问题是canPerformAction:当我点击Button或TableView时,会触发withSender方法。此外,这段代码在iOS 9.0下工作正常。

@interface MessageDetailViewController ()

- (void)updateDetailView;
- (void)setMessageBar;
- (void)setCallButton;

@end

@implementation MessageDetailViewController
{
}

@synthesize messageField;
@synthesize messageList;
@synthesize messageBarView;
@synthesize navigationBarView;

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"MessageDetailView: viewDidLoad method called.");

    // Observe keyboard hide and show notifications to resize the text view appropriately.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didHideEditMenu:) name:UIMenuControllerDidHideMenuNotification object:nil];

    [messageField becomeFirstResponder];

    messageArray = [[NSMutableArray alloc] init];
    typingImage         = [[UIImageView alloc] init];
    presenceImage       = [[UIImageView alloc] init];
    navigationBarView   = [[UIView alloc] init];
    viewHeight = self.view.frame.size.height;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];

    [messageField setDelegate:self];

    messageList.delegate = self;
    messageList.dataSource = self;

    [self updateDetailView];
    [messageList reloadData];
}

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

/**
 * This method is called to send instance method to server.
 */
- (void)onSendMessageButtonPressed:(id)sender
{
    if([messageField.text length] == 0)
    {
        return;
    }

    messageField.text = [messageField.text substringToIndex:160];

    [[DatabaseManager getDatabaseManager] addMessageInDatabase:messageField.text];

    [messageField setText:@""];

    [self updateDetailView];
    [messageList reloadData];
}

-(void)handleLongPress : (UILongPressGestureRecognizer *)gesture
{
    TableViewCell *cell = nil;
    UIMenuController *menu = [UIMenuController sharedMenuController];
    if(gesture.state == UIGestureRecognizerStateBegan)
    {
        CGPoint p = [gesture locationInView:self.messageList];

        NSIndexPath *ip = [self.messageList indexPathForRowAtPoint:p];
        rowPosition = ip.row;
        NSLog(@"row = %d", ip.row);

        if(ip)
        {            
            cell = (TableViewCell *)[messageList cellForRowAtIndexPath:ip];
            [self becomeFirstResponder];

            [menu setMenuItems:nil];

            UIMenuItem *copyMenuItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"COPY_MESSAGE", @"") action:@selector(copyMessage:)] autorelease];
            UIMenuItem *deleteMenuItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"DELETE_MESSAGE", @"") action:@selector(deleteMessage:)] autorelease];

            if(cell.imFailIndication.image != nil)
            {
                UIMenuItem *resendMenuItem = [[[UIMenuItem alloc] initWithTitle:NSLocalizedString(@"RESEND_MESSAGE", @"") action:@selector(resendMessage:)] autorelease];
                [menu setMenuItems:[NSArray arrayWithObjects:copyMenuItem, deleteMenuItem, resendMenuItem, nil]];
            }
            else
            {
                [menu setMenuItems:[NSArray arrayWithObjects:copyMenuItem, deleteMenuItem, nil]];
            }

            [menu setTargetRect:cell.frame inView:cell.superview];
            [menu setMenuVisible:YES animated:YES];
            return;
        }
    }
}

- (void)copyMessage:(id)sender 
{
    MessageDetailInfo *detailMessageInfo = [messageArray objectAtIndex:rowPosition];
    [UIPasteboard generalPasteboard].string = detailMessageInfo.message;
}

- (void)deleteMessage:(id)sender 
{
    messageDeleteActionSheet = [[UIActionSheet alloc]  initWithTitle:NSLocalizedString(@"PROMPT_MESSAGE_DELETE_CONFIRMATION", @"") delegate:self cancelButtonTitle:NSLocalizedString(@"CANCEL_BTN_TITLE", @"") destructiveButtonTitle:NSLocalizedString(@"DELETE_BTN_TITLE", @"") otherButtonTitles:nil, nil];
    [messageDeleteActionSheet showFromTabBar:self.tabBarController.tabBar];
}

/*
 The view implements this method to conditionally enable or disable commands of the editing menu. 
 The canPerformAction:withSender method is declared by UIResponder.
 */

- (BOOL)canPerformAction:(SEL)action withSender:(id)sender 
{   
    UIMenuController *menu = (UIMenuController *)sender;

    switch ([[menu menuItems] count]) 
    {
        case 0:
            //This case is to display paste option for Message text field.
            if(action == @selector(paste:))
            {
                return YES;
            }
            break;

        case 2:
            if(action == @selector(copyMessage:) || action == @selector(deleteMessage:))
            {
                return YES;
            }
            break;
        case 3:
            if(action == @selector(copyMessage:) || action == @selector(deleteMessage:) || action == @selector(resendMessage:))
            {
                return YES;
            }
            break;

        default:
            break;
    }
    return NO;
}

- (void)keyboardWillShow:(NSNotification *)notification
{   
    /*
   Reduce the size of the text view so that it's not obscured by the keyboard.
     Animate the resize so that it's in sync with the appearance of the keyboard.
     */

    NSDictionary *userInfo = [notification userInfo];

    // Get the origin of the keyboard when it's displayed.
    NSValue* aValue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];

    // Get the top of the keyboard as the y coordinate of its origin in self's view's coordinate system. The bottom of the text view's frame should align with the top of the keyboard's final position.
    CGRect keyboardRect = [aValue CGRectValue];

    // Get the duration of the animation.
    NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration;
    [animationDurationValue getValue:&animationDuration];

    // Animate the resize of the text view's frame in sync with the keyboard's appearance.
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:animationDuration];

    /* change position of messageBarView based on visibility of keypadview. */
    CGRect messageBarFrame = messageBarView.frame;
    messageBarFrame.origin.y =  viewHeight - keyboardRect.size.height - messageBarView.frame.size.height;
    messageBarView.frame = messageBarFrame;

    if(messageBarFrame.origin.y == (viewHeight - keyboardRect.size.height - messageBarView.frame.size.height))
    {
        [messageField becomeFirstResponder];
    }

    /* change height of messageList based on visibility of keypadView. */
    CGRect messageListFrame = messageList.frame;
    messageListFrame.size.height = messageBarView.frame.origin.y;
    messageList.frame = messageListFrame;

    [UIView commitAnimations];

    /* scroll to table view at last message if messages are available. */
    if ([messageList numberOfRowsInSection:0])
    {
        [messageList scrollToRowAtIndexPath:[NSIndexPath indexPathForRow ([messageList numberOfRowsInSection:0] - 1) inSection:0] atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }
}

- (void)keyboardWillHide:(NSNotification *)notification
{    
    NSDictionary* userInfo = [notification userInfo];

    /*
     Restore the size of the text view (fill self's view).
     Animate the resize so that it's in sync with the disappearance of the keyboard.
     */
    NSValue *animationDurationValue = [userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    NSTimeInterval animationDuration;
    [animationDurationValue getValue:&animationDuration];

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:animationDuration];

    /* change position of messageBarView based on visibility of keypadview. */
    CGRect newFrame = messageBarView.frame;
    newFrame.origin.y = self.view.frame.size.height - messageBarView.frame.size.height;
messageBarView.frame = newFrame;

    /* Don't update tableview if datasource has been set nil. */
    if(messageList.dataSource != nil)
    {
        /* change height of messageList based on visibility of keypadView. */
        CGRect messageListFrame = messageList.frame;
        messageListFrame.size.height = messageBarView.frame.origin.y;
        messageList.frame = messageListFrame;
    }

    [UIView commitAnimations];
}

- (void)didHideEditMenu:(NSNotification *)notification
{
    [[UIMenuController sharedMenuController] setMenuItems:nil];
}

- (void)didReceiveMemoryWarning
{
    /* Releases the view if it doesn't have a superview. */
    [super didReceiveMemoryWarning];
    /* Release any cached data, images, etc that aren't in use. */
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    /* Release any retained subviews of the main view. 
 e.g. self.myOutlet = nil; */
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIMenuControllerDidHideMenuNotification object:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    messageList.delegate = nil;
    messageList.dataSource = nil;
}

-(BOOL)navigationShouldPopOnBackButton
{
    NSLog(@"navigationShouldPopOnBackButton appearedFromComposeView = %d", [[NSNumber numberWithBool:appearedFromComposeView] intValue]);
    if(appearedFromComposeView)
    {
        [self.navigationController popToRootViewControllerAnimated:YES];
    }

    return YES; // Process 'Back' button click and Pop view controler
}

- (void)dealloc
{
    [messageField release];
    [messageList release];
    [messageBarView release]
    [messageArray release];
    [super dealloc];
}

@end

0 个答案:

没有答案