Передача данных обратно из дочернего контроллера представления

Я новичок, и у меня есть проект, в котором мне нужно передать данные обратно из дочернего контроллера. В частности, у меня есть представление выбора в моем контейнере, и я хочу иметь возможность использовать его для выбора параметра (скажем, чтобы упростить выбор цвета из массива из десяти цветов). Затем я хотел бы иметь доступ к выбранному цвету в моем родительском контроллере представления и что-то с ним делать. Я исследовал это в течение нескольких дней, и самый близкий ответ на то, что я ищу, я нашел в соответствующем вопросе на S.O. Вот:

«Что касается передачи значения контроллеру containerView, вы можете создать свойство в ChildViewController значения, которое вы хотите передать. Затем в вашем ParentViewController сделайте что-то вроде следующего:

self.ChildViewController.yourProperty = yourValue

Обратное можно сделать 4 способами:

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

Вы можете опубликовать уведомление в своем ChildViewController и добавить родительский контроллер в качестве наблюдателя.

Вы можете использовать КВО.

И самый простой выход, вы можете создать свойство в вашем parentviewController и получить к нему доступ следующим образом:

((YourParentViewControllerClassType *)self.parentViewController).yourParentProperty = TheValueYouWant;

Теперь я хотел бы сначала попробовать четвертый вариант, поскольку делегирование, kvo и так далее — это варианты, о которых я читал, но еще не готов взяться за них. В чем мне нужна помощь, так это в последнем варианте.

Скажем, у меня есть свойство в моем дочернем контроллере представления, где я храню выбранный цвет. Что-то типа:

@interface ViewController ()

@property NSString *ChosenColorInChildVC;

@end

И потом, позже:

self.ChosenColorInChildVC = [self pickerView:myPickerView titleForRow:[myPickerView selectedRowInComponent:1] forComponent:1]];

как бы я передал это значение, используя предложенный:

((YourParentViewControllerClassType *)self.parentViewController).yourParentProperty = TheValueYouWant;

Может ли кто-нибудь еще немного поглумиться для меня? Спасибо


person Paul    schedule 23.01.2016    source источник


Ответы (3)


Я собираюсь объяснить вам на примере, как работает делегирование.

Отредактируйте свой ChildViewController.h следующим образом:

@protocol ChildViewControllerDelegate; 

@interface ChildViewController : UIViewController

@property (weak)id <ChildViewControllerDelegate> delegate;

@end

@protocol ChildViewControllerDelegate <NSObject > 

- (void) passValue:(UIColor *) theValue;

@end

В вашем ChildViewController.m, когда вы хотите передать что-то обратно в ParentViewController , сделайте следующее:

 - (void) myMethod
 {
   [delegate passValue:[UIColor redColor]]; // you pass the value here
 }

На вашем ParentViewController.h

#import "ChildViewController.h"

@interface ParentViewController : UIViewController <ChildViewControllerDelegate >  // you adopt the protocol
{
}

На вашем ParentViewController.m:

- (void) passValue:(UIColor *) theValue
   {
      //here you receive the color passed from ChildViewController
   }

Теперь будьте осторожны. Все будет работать, только если вы установите делегат. Поэтому, когда вы объявляете ChildViewController внутри вашего класса ParentViewController, сделайте следующее:

ChildViewController * controller = [[ChildViewController alloc]initWithiNibName:@"ChildViewController"];
controller.delegate = self; //without this line the code won't work!
person metronic    schedule 23.01.2016
comment
Привет Метроник. Спасибо за это, это была огромная помощь. Я сделал все, что вы сказали, и (я думаю) понял логику большей части этого. За исключением последнего бита, который вы написали: На вашем ParentViewController.m: -(void) passValue:(UIColor *) theValue { // здесь вы получаете цвет, переданный от ChildViewController} Я более или менее понимаю идею, стоящую за этим, но как это действительно работает на практике. Скажем, я выбрал красный цвет в своем контейнере. как я могу получить к нему доступ в моем родителе, используя этот метод? что-то вроде: UIColor *myReceivedColor = [self passValue:???]; - person Paul; 24.01.2016
comment
Нет, вы получите данные внутри метода - (void) passValue:(UIColor *) theValue; Поставьте точку останова в этом методе, чтобы убедиться, что он работает, вы можете получить к нему доступ следующим образом: UIColor *myReceivedColor = theValue; - person metronic; 24.01.2016
comment
ХОРОШО. Извини за это. Я вообще не знаком с концепцией получения значений внутри метода. Итак, чтобы убедиться, что я вас понимаю. Нужно ли мне что-то писать внутри метода -(void) passValue:(UIColor *) theValue{} в моем Parent? И если я хочу получить доступ к цвету в моем родителе... Я пытался написать буквально UIColor *myReceivedColor = theValue; и он возвращается с использованием необъявленного идентификатора: theValue. Я также пробовал UIColor *myReceivedValue = [self passValue:theValue]; - person Paul; 24.01.2016
comment
Я также пробовал это [self passValue: [self.controller.colors objectAtIndex: [self.controller.myPickerView selectedRowInComponent: 0]]]; - person Paul; 24.01.2016
comment
Кажется, я знаю, почему это не работает. Ваша строка: ChildViewController * controller = [[ChildViewController alloc]initWithiNibName:@ChildViewController]; выдает ошибку: нет видимого @interface для ChildViewController, объявляет селектор initWithNibName' - person Paul; 25.01.2016

@metronic прав; использовать делегирование.

Также обычно вы включаете отправителя в свои методы делегата:

-(void) childViewController:(ChildViewController*)viewController passValue:(UIColor*) theValue 
person BoombaleOsby    schedule 23.01.2016

Отмечено: это очень важно.

Напишите код объявления протокола над строками #import, например.

@протокол -----

@конец

импорт ----

@имя класса интерфейса ---

person anson    schedule 29.10.2017