UIViewController parentViewController доступ к свойствам - PullRequest
2 голосов
/ 10 марта 2010

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

У меня 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];

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

Ответы [ 3 ]

13 голосов
/ 17 марта 2010

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

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

@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.h импортируйте subviewcontroller.h и используйте его делегат

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

В вашем parentviewcontroller.m реализуйте метод делегата

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

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

0 голосов
/ 25 ноября 2010

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

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

Я работаю над этим, добавляя частную категорию в 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, чтобы модальное представление могло показать, как оно было представлено, и соответствующим образом отклонить себя.

0 голосов
/ 10 марта 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...