Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > iOS > Как переключиться между двумя ViewController?


Автор: Dimanoss 22.7.2013, 10:14
День добрый, о, всезнающий All.

Воткнулся в простенькую проблемку.  Не могу переключиться между двумя ViewController'ами.  Если в StoryBoard тупо рисую кнопку и связываю - всё, конечно, работает.  Но мне нужно, чтобы по нажатию на кнопку проходила аутентификация, а только потом уж - смена экрана.

Если можно, ткните мордахой в примерчик, как программно (в смысле - не с помощью StoryBoard) можно это осуществить.  Да и в целом вопросец - как научить один контроллер видеть объекты/переменные другого....

Спасибо заранее...

Автор: Bitter 22.7.2013, 10:34
Ууууу, да у вас знания на уровне ХэлоВорда, а читать книжки это дьявол придумал  smile 

Цитата(Dimanoss @  22.7.2013,  10:14 Найти цитируемый пост)
как программно (в смысле - не с помощью StoryBoard) можно это осуществить

[self presentViewController:vc animated:YES completion:nil];

Цитата(Dimanoss @  22.7.2013,  10:14 Найти цитируемый пост)
 как научить один контроллер видеть объекты/переменные другого

#import "ДругойВьюКонтроллер.h"

Автор: Dimanoss 22.7.2013, 10:58
Цитата(Bitter @ 22.7.2013,  10:34)
Ууууу, да у вас знания на уровне ХэлоВорда, а читать книжки это дьявол придумал  smile 


Грешно, дядечка, над убогими смеяться.  Как раз над книжками и сижу.  Но там всё на уровне примеров, с классификацией не так всё гладенько, вот и не работают стандартные приёмчики, там описанные...

Автор: Bitter 22.7.2013, 11:38
Есть еще такой вариант:
делаете в сторибоарде переход как и делали раньше, но только не от кнопки, http://gyazo.com/2785476c237aa115390ced14a48d2dc9.png. Даете переходу http://gyazo.com/1fca961ade834ac7a47f122dc5749ec0.png, а в обработчике кнопки пишете

Код

- (void)didTouchButton:(id)sender {
    if (YES) {
        [self performSegueWithIdentifier:@"MySegue"];
    }
}


вместо if (YES) - ваше условие

Автор: Dimanoss 22.7.2013, 17:09
Цитата(Bitter @  22.7.2013,  10:34 Найти цитируемый пост)
#import "ДругойВьюКонтроллер.h" 


хмммм... не срастается чего-то.  Есть три ВьюКонтроллера - первый/второй + "свитчер".  Когда подключаю (#import) в m-файле первого контроллера h-файл второго, то при обращении идёт ошибка "Use of undeclared identifier".... Не видит объект, который в "свитче" нормально видим...  Что-то я явно не туда подключаю, получается... :-(

Автор: Bitter 22.7.2013, 18:49
что такое "свитчер" и как вы пытаетесь обращаться?

Автор: anatox91 8.8.2013, 22:13
забей ты на все эти сторибоарды, мой тебе совет, создавай Empty Project и пиши проект с нуля(ну или почти с нуля smile ), быстрее разберешься smile

Автор: Dimanoss 13.8.2013, 12:44
Опять к проекту.  В азах, видимо, плутаю.  Те самые два ВьюКонтроллера.  Вызов не работает. Файлы:

 BIDFirstViewController.h:
Код

#import <UIKit/UIKit.h>
@interface BIDFirstViewController : UIViewController
- (IBAction)firstButtonPressed;
@end



 BIDFirstViewController.m:
Код

#import "BIDFirstViewController.h"
#import "BIDSecondViewController.h"
@interfaceBIDFirstViewController ()
@end
@implementation BIDFirstViewController

-(IBAction)firstButtonPressed
{
    [self presentViewController:[color=red]BIDSecondViewController[/color] animated:YES completion:nil];
}
@end



 BIDSecondViewController.h:
Код

#import <UIKit/UIKit.h>
@interface BIDSecondViewController : UIViewController
- (IBAction)secondButtonPressed;
@end



 BIDSecondViewController.m:
Код

#import "BIDSecondViewController.h"
@interfaceBIDSecondViewController ()
@end
@implementation BIDSecondViewController
@end



На выделенную красным строку в  BIDFirstViewController.m компилятор ругается (Unexpected interface name, expected expression)

где-то я опять пролетаю, да?  Надо как-то явно второй контроллер именовать?

Автор: Bitter 13.8.2013, 14:41
[self presentViewController:BIDSecondViewController animated:YES completion:nil];

Что это вообще? Вы передаете туда имя класса, а не контроллер. Разницу между объектом и классом понимаете?

Автор: Dimanoss 13.8.2013, 15:22
Изначально такой вот вариант был:
Код

BIDSecondViewController *svc;
[selfpresentViewController:svc animated:YEScompletion:nil];


но оно ошибку вызывало "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present a nil modal view controller on target BIDFirstViewController...."

Вот и пытался попробовать через имя класса...  Понимаю, фигню задумал...


Автор: Bitter 13.8.2013, 16:24
Цитата(Dimanoss @  13.8.2013,  15:22 Найти цитируемый пост)
BIDSecondViewController *svc;
[selfpresentViewController:svc animated:YEScompletion:nil];


Это не меньшая фигня чем предыдущая.
Вы либо читаете не те книги, либо просто обманываете, что читаете. Так как совершенно не знаете что такое ООП, и как им пользоваться.
В данном случае вы просто объявили переменную класса BIDSecondViewController, а вам нужно создать объект этого класса. Переменная при объявлении имеет значение nil, то есть пустоту. А сообщение  'Application tried to present a nil modal view controller on target BIDFirstViewController...." означает что нельзя показать на экране контроллер, которого не существует (то есть nil)

Автор: Dimanoss 13.8.2013, 16:31
Момент.  Получается - при объявлении класса как таковой объект не создаётся?  А как быть с первым контроллером?  Я его явно не создавал, а он, тем не менее - на экране... (ошибка вылетает при обратке клика на кнопке)

Автор: Bitter 13.8.2013, 20:35
Первый контроллер создается автоматически сторибоардом. Вы можете воспользоваться сторибоардом для создания контроллера,
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboard" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"MyViewController"];

Имя контроллера прописывается в самом контроллере в сторибоарде в поле Storyboard ID

Автор: Shklyar 13.8.2013, 23:08
Использовать сторибоард можно, но может попробовать все-таки создать объект?
Как-то так: BIDSecondViewController *svc = [[BIDSecondViewController alloc] init];

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

Автор: Bitter 13.8.2013, 23:22
к предыдущему контроллеру можно перейти вызвав внутри второго контроллера метод [self dismissViewControllerAnimated:YES completion:nil]
или если он был запушен в NavigationController то [self.navigationController popViewControllerAnimated:YES]
то же самое можно сделать в первом контроллере по отношению к второму: [vc dismissViewControllerAnimated:YES completion:nil] и без изменений [self.navigationController popViewControllerAnimated:YES]

Цитата(Shklyar @  13.8.2013,  23:08 Найти цитируемый пост)
но может попробовать все-таки создать объект?

Да пожалуйста, можно и кодом, это уж зависит от предпочтений программиста и заказчика. Просто речь изначально шла о сторибоарде

Добавлено через 4 минуты и 58 секунд
в добавление к перечисленным методам возврата в предыдущий контроллер, хочу сказать, что в сторибоарде для этого есть еще одна фишка. Называется Exit
user posted image
для этого надо в первом контроллере написать аутлет принимающий сегвей, а потом в сторибоарде для второго контроллера указать метод первого просто перетащив сегвей с кнопки на эту зеленую иконку (звучит запутанно но в реализации очень просто).

Автор: Shklyar 13.8.2013, 23:43
Ну вот первый метод ( [self dismissViewControllerAnimated:YES completion:nil] ) я таки пробовал и в результате был белый экран, а не то, что я показывал перед переходом в другой вью контроллер. Т.е. переход, как я понял, таки был, но состояние было потеряно (ARC?). Если так, то в чем разница этого метода и парадигмы или алгоритма "запушить вью контроллер"?

Автор: Dimanoss 14.8.2013, 09:30
 Итак, граждане, спасибо за беспокойство, всё разрешилось чудесным образом.  Чего-то вчера психанул, сделал всё то же самое, но заново.  Всё заработало!  Блин, исходники сравниваю - всё идентично выглядит, но один проект глючит, а второй работает.  Извините за дурные потуги - от отчаяния уже начал что попало пробовать...  Спасибо за выдержку и многотерпение...  Отдельное спасибо за советы и "плюхи"...  smile 

Автор: Bitter 14.8.2013, 10:16
Shklyar, если у тебя все контроллеры находятся внутри навигэйшена то вызов dismissViewController приведет к удалению всего навигэйшена вместе со всей иерархией, которая была в нем. Так что если ты своему контроллеру делал pushViewController вместо presentViewController, то есть другими словами запушил ) то в этом случае надо делать [self.nav popViewController]

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)