2013-04-03 1 views
2

У меня есть HomeViewController, у которого есть таблицаView, заполненная массивом tableViewArray (изначально пустая). Когда я нажимаю на barButton, я перехожу к другому контроллеру View, который называется OutsideViewController, который имеет другой tableView, заполненный другим массивом.Добавить объекты в массив из другого контроллера View

То, что я хотел бы сделать это следующим образом:

Когда я нажимаю на строку в моем OutsideViewController, я хотел бы добавить выбранное значение строки в tableViewArray так, что, когда я возвращаюсь к HomeViewController, в tableView имеет этот новый элемент, указанный в таблицеView.

До сих пор, это то, что я пробовал:

В -didSelectRowAtIndexPath методе моей OutsideViewController.m у меня есть этот кусок кода:

NSString *selectedRow = [outsideArray objectAtIndex:indexPath.row]; 
NSMutableArray *temporaryArray = [NSMutableArray arrayWithObject:selectedRow]; 

HomeViewController *homeVC = [[HomeViewController alloc] init]; 
homeVC.tableViewArray = temporaryArray; 

, что код работает, но Tableview в HomeViewController еще пуста когда я вернусь. Нужно ли перезагружать данные tableView? Я делаю это правильно?

Это, как я настроил мой взгляд контроллеров в раскадровке:

HomeViewController -(modal segue)-> Navigation Controller --> OutsideViewController 

Кроме того, возвращение из OutsideViewController к HomeViewController осуществляется с помощью этой строки кода:

[self dismissViewControllerAnimated:YES completion:^{ }]; 
+0

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

ответ

4

Что вы» Повторяю неправильно, вы назначаете новый HomeViewController. Что бы я сделал, это keeep ссылку на ваш HomeViewController в вашем OutsideViewController. Вот как.

Во-первых, в OutsideViewController.h, создать свойство, например:

@property (nonatomic, weak) HomeViewController *homeVC; 

Не забудьте добавить @class HomeViewController; в вашем .h и #import "HomeViewController.h" в вашем .м

В HomeViewController, реализовать prepareForSegue: метод, как это (замените ModalSegueIdentifier с идентификатором вашего SEGUE в):

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 
    if ([segue.identifier isEqualToString:@"ModalSegueIdentifier"]) { 
     OutsideViewController *modalVC = (OutsideViewController*)segue.destinationViewController; 
     modalVC.homeVC = self; 
    } 
} 

Затем в OutsideViewController.m, вместо того, чтобы делать:

HomeViewController *homeVC = [[HomeViewController alloc] init]; 
homeVC.tableViewArray = temporaryArray; 

ли это:

_homeVC.tableViewArray = temporaryArray; 

При выходе из модального VC, ваш HomeVC будет иметь правильный массив. Не забудьте освежить свой UITableView!

NB: Конечно, есть много других способов, и это, возможно, не самый лучший. Но все-таки это должно сработать.

+0

Это просто отлично, мне просто пришлось изменить строку: «OutsideViewController * modalVC = (OutsideViewController *) segue.destinationViewController;' to' OutsideViewController * modalVC = (OutsideViewController *) [segue.destinationViewController topViewController]; 'из-за навигации Контроллер между видами –

+0

Рад, что вы заработали! – rdurand

1

Вы можете добиться этого также с помощью делегирования. Вы должны создать протокол в своем OutsideViewController с помощью метода, который отвечает за отправку нового объекта на ваш HomeViewController.Делайте это в OutsideViewController.h:

@protocol OutsideViewDelegate <NSObject> 
- (void)OutsideViewController:(OutsideViewController *)controller didAddObject:(NSString *)object; 
@end 

В файле реализации вы должны изменить немного в didSelectRowAtIndexPath: метод:

NSString *selectedRow = [outsideArray objectAtIndex:indexPath.row]; 
[self.delegate OutsideViewController:self didAddObject:selectedRow]; 

В вашем HomeViewController.h вы должны сделать ваш класс соответствует к протокол:

@interface HomeViewController : UIViewController <OutsideViewDelegate> 

После, создать свойство для делегата:

@property (nonatomic, weak) id <OutsideViewDelegate> delegate; 

Для завершения процесса реализации протокола в вашем HomeViewController.m, чтобы получить новый объект из OutsideViewController:

- (void)OutsideViewController:(OutsideViewController *)controller didAddObject:(NSString *)object 
{ 
    if (object != nil) 
    { 
      [self.tableViewArray addObject:object]; 
    } 

    [self dismissViewControllerAnimated:YES completion:nil]; 
} 

Код выше, зависит от того, если ваш tableViewArray объект является изменяемым или нет. Если это не так, вы можете изменить тип аргумента объекта в методе протокола на объект inmutable array и просто назначить tableViewArray новому массиву.

EDIT:

В методе prepareForSegue: не забудьте установить делегат:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
    if ([[segue identifier] isEqualToString:@"SEGUE_IDENTIFIER"]) { 
     OutsideViewController *outsideVC = (OutsideViewController *)[segue destinationViewController]; 
     [outsideVC setDelegate:self]; 
    } 
} 
+0

Если я использую делегирование, имеет ли значение, что у меня есть этот контроллер навигации между представлениями? –

+0

думаю нет. Если я не ошибаюсь, делегация работает с viewController, который реализует метод протокола. Он не должен влиять на другие контроллеры. Поправьте меня если я ошибаюсь. – thxou

0

Прежде всего убедитесь, что вы alloc, init ваш tableViewArray в HomeViewController

Второй , В этой строке

HomeViewController *homeVC = [[HomeViewController alloc] init] 

вы создаете новую ссылку на ваш HomeViewController, которая не является правильным, вам необходимо пройти правильную ссылку, возможно создание переменной HomeViewController в вашем OutsideViewController

Даже если вы правильно сделать первое и второе предложение вы все еще видите пустой табличный вид, потому что вы не перезагружаете tableview, так или иначе вам нужно запустить метод [self.tableview reloadData];.

Это значит; Вы должны научиться Делегирование или NSNotifications шаблон для связи между ляющих> родительские сценарии

How do I set up a simple delegate to communicate between two view controllers?

http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_nsnotificationcenter/

Для вашего вопроса просто создать делегат в вашем Outside; в вашем OutsideViewController.h

#import <UIKit/UIKit.h> 

@protocol OutsideDelegate; 

@interface{}//bunch of interface stuff 

// Declare a property for the delegate 
@property (weak) id <OutsideDelegate> delegate; 
@end 

// Protocol Header 
@protocol OutsideDelegate <NSObject> 
@optional 
- (void)dismissPop:(NSMutableArray *)list; 
@end 

в вашем OutsideViewController.m

@synthesize delegate; 


//run delegate method 
[delegate dismissPop:temporaryArray]; 
[self dismissViewControllerAnimated:YES completion:^{ }]; 

в вашем HomeViewController.ч

#import "OutsideViewController.h" 
@interface OutsideViewController : UITableViewController<OutsideDelegate> 
{} 
@property (strong, nonatomic) OutsideViewController *pvc; 

в вашем HomeViewController.m

@synthesize pvc; 

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 

    if ([[segue identifier] isEqualToString:@"your segue"]) { 
     pvc = [segue destinationViewController]; 
     [pvc setDelegate:self]; 
    } 
} 
// delegate callback function 

- (void)dismissPop:(NSMutableArray *)list { 

    self.tableViewArray=list; 
    [self.tableView reloadData]; 
} 

Другим решением было бы

Измените свой стек вид на это:

Navigation Controller --> HomeViewController -(push segue)--> OutsideViewController 

и применять rdurand «s ответ

и добавить к вашему HomeViewController:

-(void)viewDidAppear:(BOOL)animated 
{ 
    [self.tableview reloadData]; 
} 

В этом решении, так как вы просто нажать-поп viewcontrollers в стеке nabigation viewDidAppear будет называться в HomeViewController каждый раз, когда вы поп OutsideViewController.

+0

Если я использую делегат, имеет ли значение, что у меня есть этот контроллер навигации между представлениями? –

+0

Нет, это не имеет значения, id это не работает. Check' delegate' настроен правильно. Я не тестировал код, но я также обновил свой ответ с помощью дополнительного решения, вам нужно узнать делегат и nsnotification рано или поздно, хотя –