【问题标题】:Use didSelectRowAtIndexPath or prepareForSegue method for UITableView?对 UITableView 使用 didSelectRowAtIndexPath 或 prepareForSegue 方法?
【发布时间】:2011-12-29 03:47:48
【问题描述】:

我正在使用情节提要,并且我有一个 UITableView。我有一个从我的表推送到详细 VC 的 segue 设置。但是我应该使用哪种方法来处理这个问题?我必须将几个对象传递给详细视图。但我是使用didSelectRowAtIndex 还是-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender

【问题讨论】:

    标签: ios objective-c iphone uitableview storyboard


    【解决方案1】:

    如果您使用prepareForSegue:sender:,那么如果您稍后决定从表格视图之外的某些控件触发转场,您将无需进行太多更改。

    prepareForSegue:sender: 消息被发送到当前视图控制器,所以我建议这样:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        // Assume self.view is the table view
        NSIndexPath *path = [self.tableView indexPathForSelectedRow];
        DetailObject *detail = [self detailForIndexPath:path];
        [segue.destinationViewController setDetail:detail];
    }
    

    在斯威夫特中:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let path = self.tableView.indexPathForSelectedRow()!
        segue.destinationViewController.detail = self.detailForIndexPath(path)
    }
    

    【讨论】:

    • 好的,你能举个例子说明如何通过基于indexPath传递一个对象来实现它。
    • self.view 不应该只是sender 吗?我什至无法让[self.view indexPathForSelectedRow] 工作,我不得不做[sender indexPathForSelectedRow];
    • 你会如何在 Swift 中做到这一点?
    • @robmayoff 感谢您为 Swift 更新此内容。我做了一些细微的修改以反映最近的语言变化。希望这对其他人有所帮助
    • prepareFroSegue... 被调用时tableView.indexPathForSelectedRow() 包含正确的值很奇怪:tableView(_:didSelectrowAtIndexPath:) 直到稍后才被调用。
    【解决方案2】:

    我这样做了,它成功了

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
        NSLog(@"Row Selected = %i",indexPath.row);
    
        [self performSegueWithIdentifier:@"testID" sender:self.view];    
    }
    

    【讨论】:

    • 这没有意义。您应该使用 segue 或表视图委托。只需从 Cell 创建一个 segue,它就会自动执行与您所做的相同的事情,而无需编写代码。
    • 如何在没有 didSelectRow 的情况下将 segue 分配给单元格?
    【解决方案3】:

    当sender为UITableViewCell时,可以让UITableView查询cell的indexPath。

        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
            if let cell = sender as? UITableViewCell {
                let indexPath = self.tableView.indexPathForCell(cell)!
                assert(segue.destinationViewController.isKindOfClass(DetailViewController))
                let detailViewController = segue.destinationViewController as! DetailViewController
                detailViewController.item = self.items[indexPath.row] // like this
            }
        }
    

    【讨论】:

      【解决方案4】:

      如果您的 tableView 属性在另一个类中并且您只有一个部分,那么您可以使用 tag 属性来存储单元格的行,例如:

      - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
      
           UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
      
           cell.tag = indexPath.row;
      
           return cell;
      }
      

      然后您可以访问它,因为sender 是同一个单元格,其标记中的行值:

      - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
      
          MyDestinationViewController *destinationViewController = segue.destinationViewController;
          destinationViewController.myProperty = [tableViewElementsArray objectAtIndex:[sender tag]]; // sender will be your cell 
      }
      

      【讨论】:

        【解决方案5】:

        self.tableView.indexPathForSelectedRow 返回选定的单元格,但不转接发件人单元格,例如未选择发件人单元格(辅助操作),或在多选情况下。最好的方法是为 segue 发件人获取 indexPath:

        - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
            __auto_type itemViewController = (id<ItemViewController>)segue.destinationViewController;
            itemViewController.senderIndexPath = [self.tableView indexPathForCell:sender];
        }
        

        在斯威夫特中:

        protocol ItemViewController {
            var senderIndexPath : IndexPath? { get set }
            var selectedIndexPaths : [IndexPath]? { get set }
        }
        
        override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
            if  let cell = sender as? UITableViewCell,
                var itemViewController = segue.destination as? ItemViewController {
                itemViewController.senderIndexPath = tableView.indexPath(for: cell)
                itemViewController.selectedIndexPaths = tableView.indexPathsForSelectedRows
            }
        }
        

        【讨论】:

          【解决方案6】:

          如果你使用prepareForSegue:,你可以检查谁是发件人并执行不同的代码

          例如在 swift 中

          override func prepareForSegue(segue: UiStoryboardSegue, sender: AnyObject?)
          {
             var senderIsTableviewCell:Bool! = sender?.isKindOfClass(UITableViewCell)
          
             if senderIsTableviewCell
             {
                 //do something
             }
          }
          

          【讨论】:

          • 只要:如果让tableViewCell = sender as? UITableViewCell { // 做点什么 }.如果 sender 无法转换为 UITableViewCell,则不会执行“做某事”。
          猜你喜欢
          • 1970-01-01
          • 2015-07-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多