Форум программистов, компьютерный форум, киберфорум
Программирование iOS/iPhone
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/15: Рейтинг темы: голосов - 15, средняя оценка - 5.00
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
1

Модальный ViewController

05.02.2014, 08:59. Показов 2875. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте!
На выходных начал щупать разработку под iOS, до этого макось даже не видел.
Вокруг столько всего непонятного, аж глаза разбегаются.

Столкнулся с проблемой.
Есть UITabViewController и внутри него 4 UIViewController'а, у каждого контроллера переопределён свой класс, а у некоторых есть ещё и потомки вью-контроллеры.
Суть в том, что каждое некое действие(переключение между табами, нажатие кнопок в навигации) нужно проверять некий параметр, пусть будет NSString *ID и, если он nil, то вызывать модально(!) ViewController(внутри с WebView). Первое, что бросается в глаза - это deprecated present/dismissModalViewController.
Не знаю как было раньше, но сейчас вызов таким образом контроллера не блокирует основной цикл событий.
Например, пишу:
C
1
2
3
4
5
6
7
8
// Где-то в классе объекта iWannaBeModal
-(NSString *)doEpicStuff
{
     int blowTheUniverse = 42/0;
     return @"Done!";
}
// ~
if(!ID){ NSString *result = [iWannaBeModal doEpicStuff]; }
Смотрю дебаггером, iWannaBeModal вызывается в отдельном потоке, а цикл событий идёт дальше. Получается, что у меня result всегда nil.

Т.к. в iWannaBeModal живёт ещё и UIWebView, то хотелось бы дождаться завершения webViewDidFinishLoad и только потом вернуть значение. В принципе, если модально вызвать iWannaBeModal, то можно внутри класса в методе webViewDidFinishLoad присвоить нужное значение переменной, а потом его забрать. Как-нибудь так:
C
1
2
[iWannaBeModal becomeModal]; // Тут цикл событий останавливается пока не пропадёт модальный виджет
NSString *result = iWannaBeModal.result;
В итоге всё упирается в то, как вызвать iWannaBeModal модально. И необходимо ли для этого создавать контроллер в IB? Сейчас его нет. Создавал, думал через аутлеты привязать, но почему-то не смог их создать и забил.

Надеюсь на вашу помощь, товарищи.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.02.2014, 08:59
Ответы с готовыми решениями:

два viewController-a
помогите изучить один нюанс на котором стопорнулся. Кто-нибудь на примере покажите как передать...

Изменить ViewController
Пользуюсь stroboard для создания интерфейса. Скажем, есть ViewController1 для ввода логина и...

xcode ViewController
Подскажите, пожалуйста, как из View выполнить ViewController -(void)googleStart без init ???????? ...

как связать ViewController со Storyboard
Помогите пожалуйста связать ViewController с Storyboard. Создала iOS Empty Project. Подключила...

14
182 / 182 / 3
Регистрация: 10.01.2013
Сообщений: 596
05.02.2014, 10:44 2
Цитата Сообщение от arsgram Посмотреть сообщение
42/0
Там exception просто валится Хоть на что-нибудь другое разделите
0
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
05.02.2014, 10:59  [ТС] 3
Цитата Сообщение от mobidevelop Посмотреть сообщение
Там exception просто валится Хоть на что-нибудь другое разделите
Не валится там исключение, это просто как пример какой-либо операции
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
05.02.2014, 12:15 4
mobidevelop, 42/0 - "Division by 0 is undefined."

arsgram, дело не в аутлетах. Просто возьмите и прочитайте, что такое аутлеты.
Для показа view "модально", у UIViewController есть метод:
Objective-C
1
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion NS_AVAILABLE_IOS(5_0);
Цитата Сообщение от arsgram Посмотреть сообщение
И необходимо ли для этого создавать контроллер в IB?
Не обязательно в IB, но для того, чтобы у одного UIViewController-а вызвать вышеупомянутый метод, нужно в него передать другой UIViewController.
1
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
12.02.2014, 12:55  [ТС] 5
zulkis, спасибо за наводку.
Всё равно не работает всё так, как я хочу.
У меня есть UITabBarController, просто на storyboard, класс я не переопределял.
У него есть UIViewController, чей класс я переопределил. Пусть будет vc1.
Есть ещё один контроллер, на которой UIWebView. Пусть он называется vc2.
Пишу:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// B vc1
-(void)viewDidLoad
{
[super viewDidLoad];
vc2 *pew = [[vc2 alloc] init];
[self presentViewController: pew animated: YES completion: nil];
}
 
//B vc2
//...
@property (nonatomic, retain) UIWebView *webView;
//...
-(void)viewDidLoad
{
[super viewDidLoad];
if(!self.webView)
{
self.webView = [[UIWebView alloc] initWithFrame: self.view.bounds];
[self.view addSubView:self.webView];
self.webView.delegate = self;
}
}
При загрузке ничего не появляется, а в аутпуте пишет:
"Attempt to present <vc2> on <UITabBarController> whose view is not in the window hierarchy!"
Не понимаю, причём тут UITabBarController? Ведь vc1, поверх которого я пытаюсь вывести vc2, - это же UIViewController.

И ещё один эпический вопрос. Например, vc2 сделал то, что от него требовалось и теперь надо его убрать + выполнить некую функцию в vc1. Как это сделать?
В Qt очень удобный механизм сигналов/слотов для такого есть, а как корректно сделать это здесь - не понимаю.
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
12.02.2014, 13:15 6
Цитата Сообщение от arsgram Посмотреть сообщение
При загрузке ничего не появляется, а в аутпуте пишет:
"Attempt to present <vc2> on <UITabBarController> whose view is not in the window hierarchy!"
Не понимаю, причём тут UITabBarController? Ведь vc1, поверх которого я пытаюсь вывести vc2, - это же UIViewController.
Дело в том, что вызов -viewDidLoad происходит до того, как стэк отображений ваших UIViewController-ов добавится на UIWindow
Пробуйте -viewDidAppear.

Цитата Сообщение от arsgram Посмотреть сообщение
И ещё один эпический вопрос. Например, vc2 сделал то, что от него требовалось и теперь надо его убрать + выполнить некую функцию в vc1. Как это сделать?
В Qt очень удобный механизм сигналов/слотов для такого есть, а как корректно сделать это здесь - не понимаю.
3 варианта:
1. Блоки (предпочтительный для конкретного отдельного действия);
2. Делегирования с реализацией/поддержкой протокола;
3. Передача через свойства target\selector и непосредственный вызов selector у target в момент совершения действия.
1
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
12.02.2014, 17:35  [ТС] 7
zulkis, спасибо, помогло, но в таком случае не появляется webVIew в vc2.
И. как я понял, viewDidAppear вызывается каждый раз, когда появляется view, в том числе и когда переключаются представления в таббаре. Каким образом тогда будет корректно сделать? В viewDidLoad инициализировать vc2, а в viewDidAppear делаеть его present?

И блоки - хм. Читал про них, но как в конкретно этом случае их использовать - не пойму.
Можно какой-нибудь простой пример?
0
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
13.02.2014, 20:30  [ТС] 8
И ещё вопрос, не в тему, но не хочется новую создавать. // а надо
Есть UIImageView, у него стоит режим Aspect to Fit, т.е. если картинка в нём высокая, то её высота устанавливается высоте представления, а ширина подтягивается с сохранением пропорций картинки.
Если картинка широкая, но низкая, то ширина дотягивается до ширины представления и картинка центрируется по высоте.
UIImageView находится в UITableViewCell. Мне нужно, чтоб при широкой картинке пустогом еста вверху и внизу не было.
Получается, мне надо менять размер UiImageView и самоё ячейки?
Долго искал на эту тему инфу - не нашел. Смотрел методы доступные, документацию - тоже не нашел.
Может, кто-нибудь подскажет?
Да данный момент такой код, но он не работает:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
 
UIImageView *thumb = (UIImageView*)[cell viewWithTag:1];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.feed[self.feedKeys[indexPath.row]][@"i"]]]];
thumb.image = image;
CGRect rect = CGRectZero;
rect.origin = CGPointMake(0.0,0.0);
rect.size.height = image.size.height;
rect.size.width = thumb.frame.size.width;
 
[thumb sizeToFit];
[cell sizeToFit];
 
return cell;
}
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
13.02.2014, 21:23 9
arsgram, пользуйтесь свойством contentMode для UIView.
0
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
13.02.2014, 21:53  [ТС] 10
zulkis, оно не работает так, как я описал. Корректно отображаются только картинки с высота>ширина, а если ширина>высоты, то появляются пустоты.
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
14.02.2014, 07:21 11
arsgram,
UIViewContentModeScaleAspectFill
The option to scale the content to fill the size of the view. Some portion of the content may be clipped to fill the view’s bounds.
Серьезно?
0
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
14.02.2014, 18:17  [ТС] 12
zulkis, да. Если задать UIImageView 150x150, например, а картинка будет 200х200, то по 50 пикселей отрежет и поставит картинку туда.
Если режим ставить UIViewContentModeScaleAspectFit, то будет всё как я до этого написал.
Мне нужен, посути, режим UIViewContentModeScaleAspectFit, но при этом чтоб если ширина>высоты, то изменялся размер UIImageView, чтоб избежать пустот сверху и внизу.

Добавлено через 16 минут
Заморочка в том, что на форме ещё элементы присутствуют, и при UIViewContentModeScaleAspectFill, если у картинки высота сильно больше ширины, то она будет вылезать за границы UIImageView вниз и перекрывать другие элементы.
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
14.02.2014, 18:36 13
Цитата Сообщение от arsgram Посмотреть сообщение
Заморочка в том, что на форме ещё элементы присутствуют, и при UIViewContentModeScaleAspectFill, если у картинки высота сильно больше ширины, то она будет вылезать за границы UIImageView вниз и перекрывать другие элементы.
Процитирую свою цитату:
Цитата Сообщение от zulkis Посмотреть сообщение
Some portion of the content may be clipped to fill the view’s bounds.
Включите clipsToBounds, если выключена.
0
0 / 0 / 0
Регистрация: 07.07.2013
Сообщений: 14
14.02.2014, 20:47  [ТС] 14
zulkis, но мне-то нужно чтоб представление картинки по вертикали соответствовало размерам картинке на нём, при этом отодвигая или подтягивая к себе элементы соседние. Поулчается, что размеры строчек в таблице должны разного размера получаться тогда.
0
686 / 613 / 43
Регистрация: 13.01.2011
Сообщений: 1,722
15.02.2014, 07:42 15
arsgram, Значит переопределяйте -layoutSubviews контейнера и от размера своей картинки уже исходите.
Двигайте/уменьшайте/увеличивайте.
0
15.02.2014, 07:42
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.02.2014, 07:42
Помогаю со студенческими работами здесь

Подвисание ViewController при переходе по UINavigationBar
Проблема такая. Имеется UINavigationBar в котором организованы переходы во ViewController. В 7...

Как из одного ViewController изменить свойства другого?
Здравствуйте! У меня приложение на UITabBarController, я хочу чтобы если пользователь нажал...

Как сохранить данные при переходе на другой ViewController?
у меня есть два вьюконтроллера на первом: кнопка перехода на второй вьюконтроллер (связь modal),...

Как открыть ViewController при нажатии на tableCell из slide menu
Добрый день, создал слайд меню. Теперь необходимо при нажатии на пункты меню показать...

Два segue, Два viewController, Одно отображение
Добрый день! Изучаю работу c segue - и столкнулся с проблемой. Какая стоит передо мной задача....

модальный режим
Возможно ли открыть окно (activity а не AlertDialog) в модальном режиме ?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru