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?

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)
}

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

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
        }
    }

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 
}

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
    }
}

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
   }
}

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.