繁体   English   中英

从另一个View Controller向数组添加对象

[英]Add objects to an Array from another View Controller

我有一个HomeViewController ,其中有一个tableView填充有数组tableViewArray (最初为空)。 当我点击barButton时,我会模态选择到另一个名为OutsideViewController视图控制器,该控制器具有另一个由不同数组填充的tableView。

我想做的是以下几点:

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

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

在我的OutsideViewController.m-didSelectRowAtIndexPath方法中,我有这段代码:

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

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

该代码有效,但是返回时HomeViewController的tableView仍然为空。 我是否需要重新加载tableView数据? 我这样做对吗?

这是我在情节提要中设置视图控制器的方式:

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

同样,从OutsideViewController返回到HomeViewController也通过以下代码行完成:

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

您做错了什么是分配新的HomeViewController 我要做的是在OutsideViewController中保留对HomeViewControllerOutsideViewController 这是怎么回事。

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

@property (nonatomic, weak) HomeViewController *homeVC;

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

NB:当然,还有很多其他方法,可能不是最好的方法。 但是仍然可以。

您也可以使用委托来实现。 您必须使用一种负责将新对象发送到HomeViewController的方法,在OutsideViewController创建一个协议。 在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对象是否可变。 如果不是,则可以将protocol方法中的object参数的类型更改为不可变的数组对象,只需将tableViewArray分配给新数组。

编辑:

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

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

首先确保您alloc ,在HomeViewController init tableViewArray

二,在这行

HomeViewController *homeVC = [[HomeViewController alloc] init]

您正在创建对HomeViewController的不正确的新引用,您需要传递正确的引用,可能在OutsideViewController创建HomeViewController变量

即使您正确地执行了第一和第二个建议,您仍然会看到一个空的tableview,因为您没有重新加载tableview,但是您还是需要触发[self.tableview reloadData]; 方法。

那意味着 您需要学习DelegateNSNotifications模式才能在子级->父级方案之间进行通信

如何设置一个简单的委托以在两个视图控制器之间进行通信?

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.h中

#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的答案

并将其添加到您的HomeViewController中:

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

在此解决方案中,由于您只是在栈堆栈中的推入式视图控制器,因此每次您在弹出OutsideViewController时,都会在HomeViewController中调用viewDidAppear

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM