Użyć metody didSelectRowAtIndexPath lub readyForSegue dla UITableView?

101

Używam scenorysów i mam UITableView. Mam konfigurację płynną, która przesuwa się z mojego stołu do szczegółów VC. Ale jakiej metody mam użyć, aby sobie z tym poradzić? Będę musiał przekazać kilka obiektów do widoku szczegółów. Ale czy używam didSelectRowAtIndexlub -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender?

Jon
źródło

Odpowiedzi:

199

Jeśli używasz prepareForSegue:sender:, nie będziesz musiał tak wiele zmienić, jeśli później zdecydujesz się wyzwolić płynność z jakiejś kontrolki poza widokiem tabeli.

prepareForSegue:sender:Wiadomość zostanie wysłana do bieżącego kontrolera widoku, więc sugeruję coś takiego:

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

W Swift:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let path = self.tableView.indexPathForSelectedRow()!
    segue.destinationViewController.detail = self.detailForIndexPath(path)
}
rob mayoff
źródło
1
Ok, czy możesz podać przykład jak to zaimplementować z przekazaniem obiektu opartego na indexPath.
Jon
4
nie powinno self.viewpo prostu sendertu być ? Nie mogłem nawet dostać się [self.view indexPathForSelectedRow]do pracy, musiałem to zrobić[sender indexPathForSelectedRow];
ladookie
Jak byś to zrobił w Swift?
Użytkownik
@robmayoff Dzięki za aktualizację tego dla Swift. Dokonałem niewielkich zmian, aby odzwierciedlić ostatnie zmiany językowe. Mam nadzieję, że to pomoże innym
Zack Shapiro,
To dziwne, że tableView.indexPathForSelectedRow()zawiera poprawną wartość, gdy prepareFroSegue...jest wywoływana: tableView(_:didSelectrowAtIndexPath:)jest wywoływana dopiero później.
Nicolas Miari
5

Zrobiłem to i zadziałało

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{

    NSLog(@"Row Selected = %i",indexPath.row);

    [self performSegueWithIdentifier:@"testID" sender:self.view];    
}
Rohit Mandiwal
źródło
11
To nie ma sensu. Należy użyć elementu płynnego LUB delegata widoku tabeli. Po prostu utwórz płynność z komórki i automatycznie wykona to samo, co zrobiłeś bez pisania kodu.
Yariv Nissim
3
jak przypisać płynność do komórki bez didSelectRow?
Morkrom
3

Gdy nadawcą jest UITableViewCell, możesz poprosić UITableView o zapytanie o wartość indexPath komórki.

    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
        }
    }
Kaz Yoshikawa
źródło
1

jeśli twoja właściwość tableView należy do innej klasy i masz tylko jedną sekcję , możesz użyć tej tagwłaściwości do przechowywania wiersza komórki, na przykład:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];

     cell.tag = indexPath.row;

     return cell;
}

Następnie możesz uzyskać do niego dostęp, ponieważ senderjest to ta sama komórka z wartością wiersza w swoim tagu:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    MyDestinationViewController *destinationViewController = segue.destinationViewController;
    destinationViewController.myProperty = [tableViewElementsArray objectAtIndex:[sender tag]]; // sender will be your cell 
}
Laszlo
źródło
1

self.tableView.indexPathForSelectedRowzwraca wybraną komórkę, ale nie łączy komórki nadawcy, np. komórka nadawcy nie jest wybrana (akcja pomocnicza) lub w przypadku wielokrotnego wyboru. Najlepszym sposobem jest pobranie indexPath dla nadawcy segue:

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

W 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
    }
}
Stanislav P.
źródło
0

Jeśli używasz prepareForSegue:, możesz sprawdzić, kto jest nadawcą i wykonać inny kod

Na przykład w swift

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

   if senderIsTableviewCell
   {
       //do something
   }
}
Eugene
źródło
2
Po prostu zrób: jeśli niech tableViewCell = sender as? UITableViewCell {// zrób coś} . Jeśli nadawcy nie można przesłać do UITableViewCell, polecenie „zrób coś” nie zostanie wykonane.
mbeaty