各位大神好!在下正在弄IOS端一个项目,以下问题我调试了好久了,一直无功而返。还望解惑,谢谢谢谢!
       
        问题场景:
               在tabBarView中一个放置了三个功能view,三个其中一个view是用来做列表的,列表我是使用tableView来实现。
       现在想在这个tableView的cell上添加弹出的menu菜单,长按触发显示这个菜单。我也试过直接在tableView添加长按事件但是效果是一样的。        问题现象:
               一开始在此tableView中长按是能长按显示menu的,而且点击tableView中某一项进而跳转到别的view再从别的view返回都是正常的。唯一有问题的地方通过tabBarView切换到另外一个tab,然后再切换回来长按后就不能显示menu了。        调试的一些发现:
               调试时发现如果界面刚显示而未去长按时,此处单步调试能进来,就能看到menu           一些关键代码: //长按的响应函数:
-(void)display:(UILongPressGestureRecognizer *)longPre{        if (longPre.state ==UIGestureRecognizerStateBegan) {
            UITableViewCell *cell = (UITableViewCell *)longPre.view;
          
            [cell becomeFirstResponder];
        
            //将选中的设备别名和设备ID名都放到app的传输器缓存里面
            //根据cell的内容来设置全局变量
            appDelegate.selectEditDevNickname = cell.textLabel.text;
            //根据cell的内容来设置全局变量
            appDelegate.selectEditDevname = cell.detailTextLabel.text;            UIMenuItem * item1 = [[UIMenuItem alloc]initWithTitle:@"编辑" action:@selector(gotoEditDevView:)];
            UIMenuItem * item2 = [[UIMenuItem alloc]initWithTitle:@"删除" action:@selector(delDev:)];
            UIMenuController * menu = [UIMenuController sharedMenuController];
            [menu setMenuItems:@[item1,item2]];            [menu setTargetRect:cell.frame inView:self.view];            [menu setMenuVisible:YES animated:YES];
     //       [cell bringSubviewToFront:menu];
          }
}//直接在tableView的cell上添加长按事件
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ///<1.>设置标识符
    static NSString * str = @"cellStr";    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:str];
    UILabel * label = nil;
    //获取当前的行号
    NSUInteger rowNo = indexPath.row;
    if([m_devArrM count] <= 0){
        return cell;
    }
    Device *dev = [m_devArrM objectAtIndex:rowNo];
    
    ///<3.>新建cell
    if (cell == nil) {
        //创建一个cell
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:str];        //添加长按事件
        if (cell.gestureRecognizers.count ==0) {
        
             UILongPressGestureRecognizer* longPre = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(display:)];
                    [cell addGestureRecognizer:longPre];
        
       }
        
        //单元格设为圆角
        cell.layer.cornerRadius = 8;
        cell.layer.masksToBounds = NO;
        
        //cell.textLabel.text = [self.arrayDS objectAtIndex:rowNo];
        //cell.detailTextLabel.text = @"lcz061403";
        
        label = [[UILabel alloc]initWithFrame:CGRectMake(SCREEN_WIDTH_V-80, 0, 80, 50)];
        label.textAlignment = NSTextAlignmentCenter;
        [cell addSubview:label];
       
        //在屏幕滚动时,只显示图像
        cell.layer.shouldRasterize = YES;
        //栅格化,必须指定分辨率,否则默认使用 * 1,生成图像!
        cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
    }
    
    //主标题样式
    cell.textLabel.text = dev.name;
    cell.textLabel.font = [UIFont systemFontOfSize:10];
    //副标题样式
    cell.detailTextLabel.text = dev.passwd;
    cell.detailTextLabel.font = [UIFont systemFontOfSize:8];
    return cell;
}//两个界面退出和进来的代理
- (void)viewWillAppear:(BOOL)animated{
    m_devArrM = [Device allDeviceFromDB:sRenderUserName];
    [self.tableView reloadData];
    return;
}- (void)viewWillDisappear:(BOOL)animated{
    self.tabBarItem.image = [UIImage imageNamed:@"tab_dev_normal.png"];  //显示选中图片
}//是否可以成为第一响应
-(BOOL)canBecomeFirstResponder{
NSLog(@"method: %s ",__func__);
    return YES;
}

解决方案 »

  1.   

    一般这种问题,最关键的地方就在于菜单的弹出和隐藏代码!
    你可以尝试去掉[self.tableView reloadData];这句代码
    另外联合调试:
      UIMenuItem * item1 = [[UIMenuItem alloc]initWithTitle:@"编辑" action:@selector(gotoEditDevView:)];
                UIMenuItem * item2 = [[UIMenuItem alloc]initWithTitle:@"删除" action:@selector(delDev:)];-(void)display:(UILongPressGestureRecognizer *)longPre
    这3个方法里面的代码中肯定又菜单隐藏打开的联动
      

  2.   


    首先谢谢你的回复。 我今天上午也找了一下确实没发现有什么联动,唯一设置隐藏或显示的地方就是 [menu setMenuVisible:YES animated:YES];  耶。  我把self.tableView reloadData]; 注销掉也没有效果。。可能我没理会你说的点,联动具体是指什么?
      

  3.   

    你长按之后触发-(void)display:(UILongPressGestureRecognizer *)longPre
    在这个代码中[menu setMenuVisible:YES animated:YES];假设是视图展示
    那同样可以设置[menu setMenuVisible:no animated:YES];
    不过这只是猜测,在调试的时候如果发现问题找不到,可以先将判断去除在进行逐步调试
    比如:
    //添加长按事件
            if (cell.gestureRecognizers.count ==0) {
            
                 UILongPressGestureRecognizer* longPre = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(display:)];
                        [cell addGestureRecognizer:longPre];
            
           }
    去掉if判断if (longPre.state ==UIGestureRecognizerStateBegan) {
                UITableViewCell *cell = (UITableViewCell *)longPre.view;
    去掉手势判断 去掉self.tableView reloadData];可以之后在一步一步加回来
      

  4.   


         嗯嗯, 我明白你意思,去掉手势,直接点击tableView的某一项就弹出menu,我刚才试了一下,通过tabBarView控制器切换回来后,一样不显示menu,说明和长按没关系。真的是郁闷无比。
         奇怪的是这个viewController只要跳到下一个由它创建的新的viewController,再通过navigationController返回来,就又正常了。我调试看了一下,依然是canBeFirstResponer 那个回调能调试进去时就能弹出menu,不能调试进去时就不能弹出menu。我在网上没找到为什么不能进去canBeFirstResponer这个回调的相关问题。
      

  5.   

    跳转到下一个视图在返回没问题,而在tab里面切换却不行
    那你查一下tab切换的时候会不会进
    - (void)viewWillAppear:(BOOL)animated{
        m_devArrM = [Device allDeviceFromDB:sRenderUserName];
        [self.tableView reloadData];
        return;
    }- (void)viewWillDisappear:(BOOL)animated{
        self.tabBarItem.image = [UIImage imageNamed:@"tab_dev_normal.png"];  //显示选中图片
    }
    每个人的tabbar的写法都不一样,有些人的写法并不会进这这些方法
      

  6.   

    另外看你的代码UIMenuController * menu = [UIMenuController sharedMenuController]; 这个写法给人的感觉有点像单例
    这样可能会导致只有最后一个cell才能使用menu
    你可以尝试每个cell都点一下的方法来测试
      

  7.   


    不对不对!
    如果是我的话
    首先:
     UIMenuItem * item1 = [[UIMenuItem alloc]initWithTitle:@"编辑" action:@selector(gotoEditDevView:)];
                UIMenuItem * item2 = [[UIMenuItem alloc]initWithTitle:@"删除" action:@selector(delDev:)];
                UIMenuController * menu = [UIMenuController sharedMenuController];
                [menu setMenuItems:@[item1,item2]];            [menu setTargetRect:cell.frame inView:self.view];
    这个我会写在一个初始化方法里面 @prop(xxx)UIMenuController * menu 作为属性存在
    然后,我display会在cell上写一个按钮点击按钮,弹出这个菜单
    然后在display里面打断点,看测试是否每次都进
    如果还是不显示 就强制使用
    [menu setMenuVisible:YES animated:YES];
    写在viewwillapp,前提是能进这个方法