Выполните родительский переход из встроенного контроллера представления

У меня есть это:

  • MyTableViewController (наследуется от UITableViewController)

    • It has a dynamic tableview with a few cells (foo, bar, qux)

  • MyViewController (наследуется от UIViewController)

    • There are some "show" segues from this controller to other view controllers
    • Он имеет UIContainerView, в который встроен MyTableViewController.

Картинка говорит тысячу слов:

встроенный uitableviewcontroller

Когда выбрана определенная ячейка, я хочу выполнить переход родительского представления (MyViewController)

  override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
         if (indexPath.section == 1 && indexPath.row == 1) {
                self.WHAT.performSegueWithIdentifier("someShowSegue1", sender: self)
         }
  }

Является ли это возможным? что я должен использовать в «WHAT»?


person sports    schedule 03.06.2015    source источник


Ответы (6)


В prepareForSegue: для вашего встроенного перехода установите viewController в новом свойстве в вашем tableViewController, назовем его parentController. И тогда вам останется только позвонить self.parentController.performSegueWithIdentifier().

EDIT: Но прежде всего, возможно, вы можете использовать существующий parentViewController, если он содержит встроенный контроллер представления.

person Zaphod    schedule 03.06.2015
comment
Каждый дочерний контроллер представления может напрямую обращаться к своему родителю с помощью parentViewController. Нам не нужно называть его, он уже доступен. Просмотрите заголовок UIViewController :) - person Sandeep; 03.06.2015
comment
О да, это правда, но это только для чтения ... Я переименую его в своем ответе. - person Zaphod; 03.06.2015
comment
Действительно, использования parentViewController было достаточно. Хотя идея была хорошая :) - person sports; 04.06.2015
comment
это отличный ответ, но что, если в контроллере дочернего представления есть данные, которые необходимо передать в переходе? как вы его проходите? потому что вызываемая функция prepareForSegue будет той, что находится в родительском контроллере представления - person A. Vin; 03.05.2016
comment
Это все еще работает, если родительские и дочерние контроллеры представления имеют разные контроллеры навигации? - person Jenita _Alice4Real; 20.10.2016
comment
@A.Vin Вы можете установить данные с помощью параметра sender, а затем получить их обратно в методе prepareForSegue. - person Zaphod; 21.10.2016
comment
@Jenita_Alice4Real Да, потому что мы говорим о переходе к встраиванию. - person Zaphod; 21.10.2016

Возможно, вы захотите рассмотреть возможность использования делегирования для решения этой проблемы, поскольку дочерний элемент tableView не выглядит так, как будто он должен отвечать за переход. Например:

// MyViewController
class MyViewController: UIViewController, MyTableViewControllerDelegate {

    func selectedMyTableViewControllerCell(cell: UITableViewCell) {
        // ... check cell type or index or whatever
        self.performSegueWithIdentifier("someValueFromCellType", sender: self)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == myTableViewControllerIdentifier {
            if let vc = segue.destinationViewController as MyTableViewController? {
                vc.delegate = self
            }
        }
    }
}

// MyTableViewController
protocol MyTableViewControllerDelegate: class {
    func selectedMyTableViewControllerCell(cell: UITableViewCell)
}

class MyTableViewController: UITableViewController {
    weak var delegate: MyTableViewControllerDelegate?

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // ... get the cell
        delegate?.selectedMyTableViewControllerCell(cell)
    }
}
person gjeck    schedule 03.06.2015

Нет необходимости создавать свойство. Только это

self.parent?.performSegue(withIdentifier: "ID", sender: self)
person Chris8447    schedule 14.01.2018

SWIFT 4

В Swift 4 больше нет parentViewController. Вы должны использовать parent для доступа к родительскому объекту и необязательно, поэтому обязательно проверяйте наличие nil там, где это необходимо.

self.parent?.performSegue(withIdentifier: "IdentifierHere", sender: self)
person Nox    schedule 13.02.2019
comment
Swift 4 no longer has parentViewController Нет, Swift сам по себе является агностическим языком и не содержит ничего, связанного с пользовательским интерфейсом. Это изменение связано не со Swift 4. Это связано с тем, что метод изменился во фреймворке - в UIKit. - person Eric Aya; 13.02.2019

Вместо этого подключите свой переход к встроенной ячейке контроллера табличного представления. Вы можете использовать разные переходы для каждого прототипа ячейки. Это избавляет вас от проверки путей к индексам или даже от реализации didSelectRow вообще.

person malhal    schedule 30.01.2017

Переход определяется от одного контроллера представления к другому и вызывается только из контроллера представления, в котором он определен. Поэтому вам нужно будет сохранить ссылку на parentViewController.

Нравится от MyViewController

if ([segueName isEqualToString: @"embedseg"]) {
    MyTableViewController * tblViewController = (MyTableViewController *) [segue destinationViewController];
    tblViewController.parentController=self;  //Storing reference of parentViewController i.e  MyViewController 
}

Теперь вы можете просто вызывать переходы, например

self.parentController.performSegueWithIdentifier("someShowSegue1", sender: self)

Надеюсь это поможет

person Sarim Sidd    schedule 03.06.2015
comment
Вы не должны хранить parentController в дочернем элементе. Контроллер встроенного табличного представления может получить доступ к своему родителю, вызвав parentViewController. - person malhal; 30.08.2019