iOS - вернуться к моему начальному контроллеру представления

Я использую раскрутку, чтобы развернуться к начальному контроллеру представления в моей раскадровке. Раскрутка работает отлично, я реализовал этот метод в своем начальном контроллере представления:

- (IBAction) unwindToInitialViewController:(UIStoryboardSegue *) unwindSegue {

}

Однако, если я попытаюсь перейти к другому контроллеру представления после раскрутки, я получу следующую ошибку:

Предупреждение: Попытка представить, чье представление не находится в иерархии окон!

Похоже, это происходит только в том случае, если я отключаюсь от контроллера представления, который отмечен как «Исходный контроллер представления» в раскадровке. Это ошибка? Должен ли я быть в состоянии расслабиться до этого начального контроллера? Другие идеи?

ИЗМЕНИТЬ:

Вот как я выполняю второй переход:

[self performSegueWithIdentifier:@"mySegue" sender:nil];

Я должен отметить, что это проблема входа/выхода из системы. Когда я вхожу в систему в первый раз, переход от моего контроллера входа к моему следующему контроллеру работает. Когда я выхожу из системы, я возвращаюсь к начальному контроллеру представления. Затем я снова вхожу в систему, и переход от моего контроллера входа к следующему контроллеру не работает.

РЕДАКТИРОВАТЬ 2:

Из дополнительных исследований я нашел его, потому что я использую делегата для входа в систему. Вход в систему асинхронный, я делаю вызов с помощью AFNetworking, и когда это делается, я вызываю своего делегата входа в систему (в данном случае VC входа). В этот момент VC для входа может перейти к представлению.

Код входа:

- (void) login: (NSDictionary *) parameters {
    [http.manager POST:url parameters:parameters success:^(AFHTTPRequestOperation *operation, NSDictionary *response) {
       [self.loginDelegate loginSuccess:response]; 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
       [self.loginDelegate loginFailure:error]; 
    }];
}

Мой логин VC, который является делегатом:

- (void) loginSuccess:(NSDictionary *) response {
    // setup user info based on response
    ...
    // Segue 
    [self performSegueWithIdentifier:@"loginSuccessSegue" sender:nil];
}

Я проверил, что я в основном потоке, когда я перехожу, и все еще не повезло. Я знаю, что AFNetworking всегда вызывает блоки успеха/неудачи и в основном потоке.

Сложная часть. Если я изменю приведенный выше код, чтобы использовать блок, а не делегат, раскадровка/переход не испортится, и я смогу без проблем входить и выходить из системы много раз.

Почему переход работает в первый раз с шаблоном делегата, но при выходе из системы (раскрутке) я не могу использовать этот переход снова?

ИЗМЕНИТЬ 3:

Дальнейшее исследование показывает, что при раскрутке моего входа в систему VC viewDidAppear вызывается дважды. При первоначальной раскрутке представление все еще находится в стеке, покажите, что оно отображается быстро, и вызывается viewDidAppear. Однако это быстро анимируется, и viewWillAppear вызывается во второй раз с другим VC. Я думаю, что это может быть корнем проблемы. Почему, когда я расслабляюсь в этом VC, он анимируется только для того, чтобы снова анимироваться?


person lostintranslation    schedule 21.09.2015    source источник
comment
Каков ваш первоначальный viewController? Кроме того, как дела со вторым переходом?   -  person JDM    schedule 21.09.2015
comment
Похоже, вы слишком рано переходите к следующему контроллеру.   -  person kirander    schedule 21.09.2015
comment
@Jay Я добавил, как я программно перехожу.   -  person lostintranslation    schedule 21.09.2015
comment
@kirander не уверен, как это возможно, поскольку я делаю это при нажатии кнопки. IE я отключаюсь от своего контроллера входа в систему и могу ждать столько, сколько захочу, прежде чем я нажму кнопку входа, и переход не сработает. Опять же, это происходит только после того, как я делаю раскрутку, работает с первого раза.   -  person lostintranslation    schedule 21.09.2015
comment
Какой объект self во втором примере перехода?   -  person Phillip Mills    schedule 21.09.2015
comment
Self — это контроллер представления входа в систему. Не должно иметь значения, что с Segue все в порядке в первый раз. Однако переход не работает после того, как я раскручиваюсь и пытаюсь снова войти в систему.   -  person lostintranslation    schedule 22.09.2015
comment
Пожалуйста, создайте небольшой проект, демонстрирующий, какой именно код работает, а какой нет.   -  person vrwim    schedule 28.09.2015


Ответы (1)


Пожалуйста, проверьте, является ли ваш loginDelegate nil во время второй попытки входа в систему. Если это nil, "вызовы делегатов" просто никуда не денутся. Также проверьте, указывает ли loginDelegate на ожидаемый экземпляр. Если он указывает на «старый» экземпляр, могут быть предприняты попытки представить неправильные представления.

Набор методов viewDidLoad, viewDidAppear, viewWillAppear и т. д. может вызываться в неожиданном порядке, особенно при возврате в навигацию или показе объявления и выходе из него. Если у вас есть разные задачи инициализации/настройки, распределенные между этими методами, вы можете получить частично инициализированный контроллер представления.

(Думая о проблеме, я потерял ваше заявление об ошибке, поэтому, вероятно, делегат не равен нулю.)

ИЗМЕНИТЬ:

Я запустил один из своих крошечных тестовых проектов раскрутки и зарегистрировал вызовы viewDidAppear:

viewDidAppear: <ViewController: 0x7a687700>
viewDidAppear: <VC2: 0x7a70e970>
viewDidAppear: <VC3: 0x7a694d50>
unwind target
viewDidAppear: <VC2: 0x7a70e970>
viewDidAppear: <ViewController: 0x7a687700>
viewDidAppear: <VC2: 0x7a71b790>
viewDidAppear: <VC3: 0x7a694d20>
unwind target
viewDidAppear: <VC2: 0x7a71b790>
viewDidAppear: <ViewController: 0x7a687700>

Выполнение раскрутки в VC3 на короткое время показывает VC2 и в конечном итоге приводит к цели ViewController. Теперь второй «логин» ведет к разным экземплярам контроллеров представления.

Сохраняете ли вы ссылки на «старые» контроллеры представления?

Другая причина может заключаться в том, что ваше обнаружение «выхода из системы» срабатывает дважды (один раз, когда идет раскрутка, и еще один раз, когда промежуточный или начальный контроллер представления обнаруживает необходимость входа в систему?).

person Rainer Schwarze    schedule 28.09.2015
comment
Это не ноль. Происходит вызов делегата. Segue пытается перейти и не может представить представление, отсюда и сообщение об ошибке. - person lostintranslation; 28.09.2015
comment
@lostintranslation Я опубликовал ответ и сразу вспомнил сообщение об ошибке :-) Я обновил ответ. - person Rainer Schwarze; 28.09.2015
comment
Тот же экземпляр :(. Проверено в отладчике. - person lostintranslation; 28.09.2015
comment
@lostintranslation После того, как я провел небольшой тест, я заметил ваши правки в отношении разных экземпляров. Я обновил свой ответ более подробно. Можете ли вы проверить, имеет ли что-либо из этого отношение к проблеме? - Спасибо и наилучшие пожелания - person Rainer Schwarze; 30.09.2015
comment
Спасибо! Я думаю, что вы совершенно правы. По какой-то причине, когда я раскручиваю, мой логин ВК отображается на секунду, затем он закрывается, а раскадровка показывает новый. У меня была ошибка в назначении делегата, которая была связана с таким поведением. - person lostintranslation; 30.09.2015
comment
Любая идея, почему unwind показывает VC только для того, чтобы закрыть его и показать снова? Если да, то есть ли способ предотвратить это. Я исправил свою ошибку, но пользовательский интерфейс уродлив, когда VC закрывается, а затем снова анимируется. - person lostintranslation; 30.09.2015
comment
Моя классическая причина подобного поведения в моем тестовом приложении — подключение перехода от кнопки вместо желтого значка контроллера представления, когда я хочу перейти вручную. Вызов PerformSegue в обработчике кнопки дважды вызывает segue. -- Возможно ли, что у вас есть два экземпляра VC в стеке контроллера представления? (Вы можете зарегистрировать их, используя self.navigationController.viewControllers.) - person Rainer Schwarze; 30.09.2015