从另一个View Controller添加对象到Array

时间:2013-04-03 13:48:04

标签: ios objective-c uitableview uiviewcontroller nsarray

我有一个HomeViewController,其中有一个用数组tableViewArray填充的tableView(最初为空)。当我点击barButton时,我会以模态方式转换到另一个名为OutsideViewController的View Controller,它有另一个由不同数组填充的tableView。

我想做的是以下内容:

当我点击OutsideViewController中的一行时,我想将所选字符串值添加到tableViewArray,以便当我返回HomeViewController时,tableView具有该值tableView中列出的新项目。

到目前为止,这是我尝试过的:

在我-didSelectRowAtIndexPath的{​​{1}}方法中,我有这段代码:

OutsideViewController.m

该代码有效但我返回时NSString *selectedRow = [outsideArray objectAtIndex:indexPath.row]; NSMutableArray *temporaryArray = [NSMutableArray arrayWithObject:selectedRow]; HomeViewController *homeVC = [[HomeViewController alloc] init]; homeVC.tableViewArray = temporaryArray; 中的tableView仍为空。我是否必须重新加载tableView数据? 我这样做了吗?

这就是我在Storyboard中设置视图控制器的方法:

HomeViewController

此外,从OutsideViewController到HomeViewController的返回是由以下代码行完成的:

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

3 个答案:

答案 0 :(得分:4)

你做错了是你分配了一个新的HomeViewController。我要做的是在你的HomeViewController中提及OutsideViewController的引用。这是如何。

首先,在OutsideViewController.h中,创建一个属性,如下所示:

@property (nonatomic, weak) HomeViewController *homeVC;

不要忘记在.h中添加@class HomeViewController;,在.m中添加#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

注意:当然,还有很多其他方式,也许不是最好的方式。但是,它应该可行。

答案 1 :(得分: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对象是否可变。如果不是,您可以将协议方法中对象参数的类型更改为不可变数组对象,并将tableViewArray分配给新数组。

修改

prepareForSegue:方法中,不要忘记设置委托:

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

答案 2 :(得分:0)

首先请确保allocinit tableViewArray HomeViewController中的HomeViewController *homeVC = [[HomeViewController alloc] init]

第二,在这一行

HomeViewController

您正在创建对OutsideViewController的新引用,这是不正确的,您需要传递正确的引用,可能在[self.tableview reloadData];

中创建HomeViewController变量

即使你正确地做了第​​一个和第二个建议,你仍然会看到一个空的tableview,因为你没有重新加载tableview,不知何故你需要触发Outside方法。

这意味着;您需要学习委派 NSNotifications 模式,以便在子级&gt;父级方案之间进行通信

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

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

对于您的问题,只需在#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.h中

@synthesize delegate;


//run delegate method
[delegate dismissPop:temporaryArray];
[self dismissViewControllerAnimated:YES completion:^{ }];
你的OutsideViewController.m

中的

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

@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];
}
HomeViewController.m中的

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

另一种解决方案

将您的视图堆栈更改为:

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

并应用 rdurand 的回答

并将其添加到HomeViewController:

viewDidAppear

在此解决方案中,因为您只是在nabigation堆栈中的push-pop viewcontrollers {{1}}将在每次弹出OutsideViewController时在HomeViewController中调用。