Изнутри контроллера представления в представлении контейнера, как вы получаете доступ к контроллеру представления, содержащему контейнер?
Это сложно для слова, но у меня есть контроллер вида (vc1), который содержит представление контейнера (я использую раскадровки). Внутри этого контейнерного представления есть контроллер навигации и контроллер корневого представления (vc2).
Внутри vc2 как я могу получить доступ к vc1?
Или, как мне передать vc1 в vc2? (имея в виду, что я использую раскадровки).
Ответы
Ответ 1
Вы можете использовать метод prepareForSegue
в Vc1, поскольку встраивание segue происходит, когда ContainerViewController создается дочерним. вы можете передать себя как obj или сохранить ссылку на дочерний элемент для последующего использования.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString * segueName = segue.identifier;
if ([segueName isEqualToString: @"embedseg"]) {
UINavigationController * navViewController = (UINavigationController *) [segue destinationViewController];
Vc2 *detail=[navViewController viewControllers][0];
Vc2.parentController=self;
}
}
Изменить: незначительное исправление кода
Ответ 2
Чтобы получить доступ к контроллеру родительского представления из вашего контроллера дочернего представления, вы должны переопределить didMoveToParentViewController:
- (void)didMoveToParentViewController:(UIViewController *)parent {
[super didMoveToParentViewController:parent];
//Use parent
}
В команде Xcode + Нажмите этот метод для получения дополнительной информации:
Эти два метода являются общедоступными для контейнерных подклассов для вызова при переходе между дочерними контроллеры. Если они переопределены, переопределения должны обеспечивать вызов супер. Родительский аргумент в оба этих метода равны нулю, когда ребенок удаляется из своего родителя; в противном случае он равен новому родительский контроллер.
addChildViewController: будет вызывать [child willMoveToParentViewController: self] перед добавлением ребенок. Однако он не будет называть didMoveToParentViewController:. Ожидается, что вид контейнера подкласс класса будет выполнять этот вызов после завершения перехода к новому ребенку или, в случай без перехода, сразу после вызова addChildViewController:. по аналогии removeFromParentViewController: не вызывает [self willMoveToParentViewController: nil] перед удалением ребенок. Это также ответственность за контейнерный подкласс. Контейнерные подклассы обычно определяют метод, который переходит к новому дочернему элементу, сначала вызвав addChildViewController:, затем выполнив который добавит новый дочерний вид в иерархию представлений своего родителя и, наконец, вызовет didMoveToParentViewController:. Аналогично, подклассы обычно определяют метод, который удаляет дочерний элемент в обратный способ путем первого вызова [child willMoveToParentViewController: nil].
Ответ 3
Используйте свойство parentViewController
как self.parentViewController
Ответ 4
Вы можете использовать делегирование с использованием того же метода, который использовал Бонни. Вот как вы это делаете:
В вашем контейнере ViewController:
class ContainerViewViewController: UIViewController {
//viewDidLoad and other methods
var delegate: ContainerViewControllerProtocol?
@IBAction func someButtonTouched(sender: AnyObject) {
self.delegate?.someDelegateMethod() //call this anywhere
}
}
protocol ContainerViewControllerProtocol {
func someDelegateMethod()
}
В родительском ViewController:
class ParentViewController: UIViewController, ContainerViewControllerProtocol {
//viewDidLoad and other methods
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "filterEmbedSegue" {
let containerViewViewController = segue.destinationViewController as ContainerViewViewController
containerViewViewController.delegate = self
}
}
func someDelegateMethod() {
//do your thing
}
}
Ответ 5
Спасибо, Бонни, что рассказала мне, что делать. Действительно, подготовка к методу segue - это путь.
Я просто уточняю код и шаги здесь.
Итак, сначала выберите segue (link) в раскадровке, которая соединяет вид контейнера с его первым контроллером представления. Я назвал свой "toContainer".
Затем в контроллере представления, содержащем представление контейнера, добавьте этот метод
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString: @"toContainer"]) {
UINavigationController *navViewController = (UINavigationController *) [segue destinationViewController];
UIViewController *vc2 = [navViewController viewControllers][0];
}
}
Итак, vc2 был контроллером, к которому я хотел получить ссылку.
Это сработало для меня, ваш метод будет немного отличаться внутри prepareForSegue, если ваш первый viewconroller не был навигационным контроллером.
Ответ 6
1) на VC2 выставляют свойство для передачи в ссылке на VC1
//VC2.h
#import "VC1.h"
@interface VC2 : NSObject
@property (strong, nonatomic) VC1 *parent;
@end
2) на VC1, передайте себя в свойство, открытое в VC2, в вашем методе prepareForSegue после того, как вы настроите свой идентификатор segue на "ToVC2". Затем передайте ссылку так:
//VC1.m
@implementation VC1
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"ToVC2"]) {
VC2 *vc2 = segue.destinationViewController;
vc2.parent = self;
}
}