2010-03-09 2 views
2

Я знаю, что этот вопрос задан несколько раз, и я прочитал существующие сообщения по этой теме, но мне по-прежнему нужна помощь.Свойства доступа родительского контроля UIViewController

У меня есть 2 UIViewControllers - родитель и ребенок. Я показываю ребенок UIViewController с помощью presentModalViewController, как показано ниже:

ChildController *child = 
[[ChildController alloc] initWithNibName:@"ChildView" bundle:nil]; 
[self presentModalViewController:child animated:YES]; 
[child release]; 

мнения ребенка имеет UIPickerView. Когда пользователь выбирает элемент из UIPickerView и клики завершены, я должен отклонить модальное представление и отобразить выбранный элемент на UITextField в родительском представлении.

В кнопке ребенка нажмите delegate, я следующее:

ParentController *parent = 
(ParentController *)[self.navigationController parentViewController]; 
[parent.myTextField setText:selectedText]; 
[self dismissModalViewControllerAnimated:YES]; 

Все работает без ошибок. Но я не знаю, как загрузить родительский вид, чтобы он отображал обновленный UITextField.

Я попытался

[parent reloadInputViews]; 

Безразлично»работу. Пожалуйста помоги.

ответ

13

Делегирование - это путь. Я знаю некоторых людей, которые могут искать более легкое решение, но поверьте мне, я пробовал других, и ничего лучше, чем делегирование. Таким образом, любой, у кого есть такая же проблема, читайте делегацию и следуйте ей шаг за шагом.

В вашем subviewcontroller.h - объявить протокол и объявить делегаты в нем.

@protocol myDelegate 
-(void)clickedButton:(subviewcontroller *)subController; 
@end 

В вашем subviewcontroller.h, в @interface:

id<myDelegate> delegate; 
@property (nonatomic, assign) id<myDelegate> delegate;  
NSString *data; 
-(NSString *)getData; 

В вашем subviewcontroller.m, синтезировать myDelegate. Добавьте следующий код туда, где вы хотите, чтобы уведомить ваше parentviewcontroller что подтаблицы делается делать то, что он должен делать:

[delegate clickedButton:self]; 

, а затем обрабатывать GetData возвращать любые данные, которые вы хотите отправить на свой parentviewcontroller

В вашем parentviewcontroller.h, импорт subviewcontroller.h и использовать его делегируют

#import "subviewcontroller.h" 
@interface parentviewcontroller : VUIViewController <myDelegate> 
{} 

В вашем parentviewcontroller.м, реализовать делегатский метод

- (void)clickedButton:(subviewcontroller *)subcontroller 
{ 
    NSString *myData = [subcontroller getData]; 
    [self dimissModalViewControllerAnimated:YES]; 
    [self reloadInputViews]; 
} 

Не забывайте, что управление памятью!

+0

+1 Это отличный ответ. Ты спасаешь мою голову. Огромное спасибо. –

+0

Thats Effin Эпический ответ чувак. Благодаря!. :-) – CalZone

0

Если на дисплее вашего модального вида появляется предупреждение с низкой памятью, представление родителя будет выгружено. Затем parent.myTextField больше не ссылается на правильное текстовое поле до перезагрузки представления. Вы можете принудительно перезагрузить представление, просто позвонив parent.view;

Однако лучше предположить, что родительский вид имеет свойство String, которое может быть установлено дочерним видом. Затем, когда родительский вид снова появится, поместите эти данные в текстовое поле, например, внутри viewWillAppear:. Вы хотите, чтобы значение было установлено на какое-то значение по умолчанию, когда родительский вид также появляется снова.

+0

viewWillAppear не срабатывает, когда дочерний модал отклоняется. Кнопка «Готово» находится внутри дочернего представления, где я получаю выбранный текст в виде выбора, а затем отклоняю модальный. родитель только что появился и не должен появляться. Я догадываюсь, поэтому он не запускает viewWillAppear. – Dave

+0

Если вы все делаете правильно, используя фреймворк так, как он предполагается использовать, следует вызвать viewWillAppear. Вы уверены, что переопределяете правильный метод в правильном классе? –

0

- (void) viewWillAppear: (BOOL) анимированный не вызывает для меня ни того, ни другого, когда это модальный контроллер. Не знаю, почему. Неправильно переопределено в любом месте этого приложения, и та же проблема возникает и в других 2 приложениях, над которыми я работаю. Я действительно не думаю, что это работает.

Раньше я использовал делегатский подход, но я думаю, что следующий подход тоже хорош.

Я работаю вокруг этого, добавив категорию, чтобы UIViewController, например, так:

.h файл:

@interface UIViewController(Extras) 
// returns true if this view was presented via presentModalViewController:animated:, false otherwise. 
@property(readonly) BOOL isModal; 
// Just like the regular dismissModalViewController, but actually calls viewWillAppear: on the parent, which hasn't been working for me, ever, for modal dialogs. 
- (void)dismissModal: (BOOL) animated; 
@end 

и .m файл:

@implementation UIView(Extras) 
-(BOOL) isModal 
{ 
    return self == self.parentViewController.modalViewController; 
} 

- (void)dismissModal: (BOOL) animated 
{ 
    [self.parentViewController viewWillAppear: animated]; 
    [self dismissModalViewControllerAnimated: animated]; 
} 
@end 

, которые я теперь могу вызовите это, когда я хочу отклонить диалоговое окно:

// If presented as a modal view, dismiss yourself. 
if(self.isModal) 
    [self dismissModal: YES]; 

и теперь viewWillAppear правильно вызывается.

И да, я жертвую бонусом 'isModal', так что модальное представление может определить, как оно было представлено, и надлежащим образом отклонить его.

Смежные вопросы