Використовувати didSelectRowAtIndexPath або підготуватиForSegue метод для UITableView?


101

Я використовую розкадровки і маю UITableView. У мене налаштування segue, яке підштовхується з мого столу до деталей VC. Але який метод я повинен використовувати, щоб впоратися з цим? Мені доведеться передати пару об'єктів до детального подання. Але я використовую didSelectRowAtIndexчи -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender?

Відповіді:


199

Якщо ви користуєтеся 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)
}

1
Гаразд, чи можете ви навести приклад того, як це реалізувати з передачею об'єкта на основі indexPath.
Іван

4
не повинно self.viewбути просто senderтут? Я навіть не міг дійти [self.view indexPathForSelectedRow]до роботи, мені довелося це зробити[sender indexPathForSelectedRow];
ladookie

Як би ти це зробив у Свіфті?
Користувач

@robmayoff Дякую за оновлення цього для Swift. Я вніс невеликі зміни, щоб відобразити останні зміни мови. Сподіваюся, що це допомагає деяким іншим
Зак Шапіро

Це дивно, що tableView.indexPathForSelectedRow()містить правильне значення, коли prepareFroSegue...викликається: tableView(_:didSelectrowAtIndexPath:)не викликається до пізніше.
Nicolas Miari

5

Я це зробив, і це спрацювало

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

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

    [self performSegueWithIdentifier:@"testID" sender:self.view];    
}

11
Це не має сенсу. Ви повинні або використовувати segue або делегат подання таблиці. Просто створіть відомість із стільника, і він автоматично виконає те саме, що ви зробили без написання коду.
Ярів Ніссім

3
як призначити пошкодження комірки без didSelectRow?
Моркром

3

Коли відправник UITableViewCell, ви можете попросити UITableView запитувати 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
        }
    }

1

якщо ваша власність 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 
}

1

self.tableView.indexPathForSelectedRowповертає вибрану клітинку, але не відокремлює відправницьку клітинку, наприклад, клітина відправника не обрана (додаткова дія), або у випадку множинного вибору. Найкращий спосіб отримати indexPath для відправника Segue:

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

0

Якщо ви використовуєте prepareForSegue: ви можете перевірити, хто є відправником, і виконати інший код

Наприклад у швидкому

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

   if senderIsTableviewCell
   {
       //do something
   }
}

2
Просто зробіть: якщо дозволити tableViewCell = відправник як? UITableViewCell {// робити щось} . Якщо відправника неможливо присвоїти UITableViewCell, "зробити щось" не виконається.
mbeaty
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.