Use didSelectRowAtIndexPath or prepareForSegue method for UITableView?

前端 未结 6 503
不思量自难忘°
不思量自难忘° 2020-11-29 16:38

I\'m using storyboards and I have a UITableView. I have a segue setup that pushes from my table to the detail VC. But which method should I use to handle this? I\'ll have

相关标签:
6条回答
  • 2020-11-29 16:47

    If you use prepareForSegue: you can check who is the sender and execute different code

    For example in swift

    override func prepareForSegue(segue: UiStoryboardSegue, sender: AnyObject?)
    {
       var senderIsTableviewCell:Bool! = sender?.isKindOfClass(UITableViewCell)
    
       if senderIsTableviewCell
       {
           //do something
       }
    }
    
    0 讨论(0)
  • 2020-11-29 16:56

    If you use prepareForSegue:sender:then you won't have as much to change if you later decide to trigger the segue from some control outside the table view.

    The prepareForSegue:sender: message is sent to the current view controller, so I'd suggest something like this:

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

    In Swift:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let path = self.tableView.indexPathForSelectedRow()!
        segue.destinationViewController.detail = self.detailForIndexPath(path)
    }
    
    0 讨论(0)
  • 2020-11-29 17:00

    I did this and it worked

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
        NSLog(@"Row Selected = %i",indexPath.row);
    
        [self performSegueWithIdentifier:@"testID" sender:self.view];    
    }
    
    0 讨论(0)
  • 2020-11-29 17:01

    if your tableView property is in another class and you only have one section, then you could use the tag property to store the cell's row like:

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

    And then you can access it as the sender is the same cell with the row value in its tag:

    - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    
        MyDestinationViewController *destinationViewController = segue.destinationViewController;
        destinationViewController.myProperty = [tableViewElementsArray objectAtIndex:[sender tag]]; // sender will be your cell 
    }
    
    0 讨论(0)
  • 2020-11-29 17:05

    When sender is UITableViewCell, you may ask UITableView to query indexPath of the cell.

        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
            }
        }
    
    0 讨论(0)
  • 2020-11-29 17:05

    self.tableView.indexPathForSelectedRow returns selected cell, but not segue sender cell, e.g. sender cell is not selected (accessory action), or in multiple selection case. The best way is getting indexPath for segue sender:

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

    In Swift:

    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
        }
    }
    
    0 讨论(0)
提交回复
热议问题