Использование делегата для передачи данных обратно в стек навигации - PullRequest
14 голосов
/ 09 марта 2011

Я боролся с передачей данных между двумя контроллерами представления уже пару дней и очень запутался. Я новичок в Objective-C и нахожу некоторые детали непростыми, чтобы успокоиться.

У меня есть контроллер навигации, FirstView - это форма, и в этой форме у меня есть кнопка, которая загружает SecondView, который содержит TableView, чтобы пользователь мог выбрать некоторые параметры. Затем я хочу передать выбор обратно контроллеру FirstView и отобразить данные и т. Д. *

Я много читал об этом (stackoverflow, iphonedevsdk, CS 193P Resources) и варианты, которые я видел,

1) ivar в приложении делегат (грязный и не рекомендуется) 2) создать синглтон 3) создать класс модели данных 4) Используйте протоколы и делегаты (рекомендуется Apple)

Я хочу сделать все правильно и хочу использовать вариант 4 - Делегаты в моей программе

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

Может ли кто-нибудь предоставить базовый пример того, как настроить и передать NSArray с использованием делегата и двух контроллеров представления.

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

Ответы [ 3 ]

30 голосов
/ 19 октября 2012

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

Вот примерный план того, как должен выглядеть код:

SecondViewController.h

@protocol SecondViewControllerDelegate;

@interface SecondViewController;

SecondViewController : UIViewController
{
    id<SecondViewControllerDelegate> delegate;

    NSArray* someArray;
}

@property (nonatomic, assign) id<SecondViewControllerDelegate> delegate;
@property (nonatomic, retain) NSArray* someArray;

@end

@protocol SecondViewControllerDelegate
- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController;
@end

SecondViewController.m :

@implementation SecondViewController

@synthesize delegate;
@synthesize someArray;

- (void)dealloc
{
    [someArray release];
    [super dealloc];
}

- (void)someMethodCalledWhenUserIsDone
{
    [delegate secondViewControllerDidFinish:self];
}

FirstViewController.h:

#import SecondViewController

@interface FirstViewController : UIViewController <SecondViewControllerDelegate>
{
    ...
}

@end

FirstViewController.m

@implementation FirstViewController

- (void)secondViewControllerDidFinish:(SecondViewController*)secondViewController
{
    NSArray* someArray = secondViewController.someArray
    // Do something with the array
}

@end
1 голос
/ 09 марта 2011

С моей головы. Вы можете заменить _returnedProperty своим пользовательским объектом, а в методе setReturnedProperty сделать всю магию, прежде чем фактически присвоить проверенное значение из таблицы.

@interface FormController : UIViewController {
    NSString *_returnedProperty;
}

@property (nonatomic, retain) NSString *returnedProperty;

@end

@implementation FormController

- (void)showChoices {
    TableController *tv = [[TableController alloc] initWithDelegate:self];
    [self.navigationController pushViewController:tv animated:YES];
    [tv release];
}

- (void)setReturnedProperty:(NSString *)string {
    NSLog(@"Setting property as a delegate");
    [_returnedProperty release];
    _returnedProperty = [string retain];
}

@synthesize returnedProperty=_returnedProperty;

@end

@interface TableController : UITableViewController {
    id _delegate
}
@end

@implementation TableController

- (id)initWithDelegate:(id)delegate {
    self = [super initWithStyle:UITableViewGroupedStyle];
    if (!self) return nil;

    _delegate = delegate;
    return self;
}

- (void)tableView:(UITableView *)tv didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    // do the data retrieval stuff
    NSString *returnedProperty = @"foo";
    [_delegate setReturnedProperty:returnableProperty];
}

@end
0 голосов
/ 21 июля 2014

Вы можете использовать раскадровку довольно просто. Используйте это в реализации SecondViewController и создайте свойство в VIewController.h (контроллер первого представления) с именем dataFromSecondView

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
  NSString *textvalue = self.SecondViewText.text;
  ViewController *destination = segue.destinationViewController;
  destination.dataFromSecondView = textvalue;
}
...