简体   繁体   English

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

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

I have a HomeViewController which has a tableView populated with the array tableViewArray (originally empty). 我有一个HomeViewController ,其中有一个tableView填充有数组tableViewArray (最初为空)。 When I tap on a barButton, I segue modally to another View Controller called OutsideViewController which has another tableView populated by a different array. 当我点击barButton时,我会模态选择到另一个名为OutsideViewController视图控制器,该控制器具有另一个由不同数组填充的tableView。

What I would like to do is the following: 我想做的是以下几点:

When I tap on a row in my OutsideViewController , I would like to add the selected string value to the tableViewArray so that when I go back to HomeViewController , the tableView has that new item listed in the tableView. 当我在OutsideViewController点击一行时,我想将所选的字符串值添加到tableViewArray以便当我返回HomeViewController ,tableView在tableView中列出该新项。

So far, this is what I have tried: 到目前为止,这是我尝试过的:

In the -didSelectRowAtIndexPath method of my OutsideViewController.m I have this piece of code: 在我的OutsideViewController.m-didSelectRowAtIndexPath方法中,我有这段代码:

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

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

That code works but the tableView in HomeViewController is still empty when I return. 该代码有效,但是返回时HomeViewController的tableView仍然为空。 Do I have to reload the tableView data? 我是否需要重新加载tableView数据? Am I doing this right? 我这样做对吗?

This is how I have set up my View Controllers in Storyboard: 这是我在情节提要中设置视图控制器的方式:

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

Also, the return from OutsideViewController to HomeViewController is done by this line of code: 同样,从OutsideViewController返回到HomeViewController也通过以下代码行完成:

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

What you're doing wrong is you're allocationg a new HomeViewController . 您做错了什么是分配新的HomeViewController What I would do is keeep a reference to your HomeViewController in your OutsideViewController . 我要做的是在OutsideViewController中保留对HomeViewControllerOutsideViewController Here is how. 这是怎么回事。

First, in OutsideViewController.h , create a property, like this : 首先,在OutsideViewController.h ,创建一个属性,如下所示:

@property (nonatomic, weak) HomeViewController *homeVC;

Don't forget to add @class HomeViewController; 不要忘记添加@class HomeViewController; in your .h, and #import "HomeViewController.h" in your .m 在.h中,并在.m中#import "HomeViewController.h"

In HomeViewController , implement the prepareForSegue: method like this (replace ModalSegueIdentifier with your segue's identifier) : HomeViewController ,实现如下的prepareForSegue:方法(将ModalSegueIdentifier替换为您的segue的标识符):

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

Then, in OutsideViewController.m , instead of doing : 然后,在OutsideViewController.m ,而不是这样做:

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

Do this : 做这个 :

_homeVC.tableViewArray = temporaryArray;

When you leave your modal VC, your HomeVC will have the correct array. 当您离开模态VC时,您的HomeVC将具有正确的阵列。 Don't forget to refresh your UITableView ! 不要忘记刷新您的UITableView

NB: Of course, there are many other ways, and it's maybe not the best one. NB:当然,还有很多其他方法,可能不是最好的方法。 But still, it should work. 但是仍然可以。

You can achieve this too using delegation. 您也可以使用委托来实现。 You have to create a protocol in your OutsideViewController with a method that is responsible for sending the new object to your HomeViewController . 您必须使用一种负责将新对象发送到HomeViewController的方法,在OutsideViewController创建一个协议。 Do this in OutsideViewController.h: 在OutsideViewController.h中执行以下操作:

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

In the implementation file you have to change a little bit the didSelectRowAtIndexPath: method: 在实现文件中,您需要稍微修改didSelectRowAtIndexPath:方法:

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

In your HomeViewController.h you have to make your class conforms to the protocol: 在HomeViewController.h中,必须使您的类符合协议:

@interface HomeViewController : UIViewController <OutsideViewDelegate>

After, create a property for the delegate: 之后,为委托创建一个属性:

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

To finish the process, implement the protocol in your HomeViewController.m to receive the new object from the OutsideViewController: 要完成此过程,请在HomeViewController.m中实现协议以从OutsideViewController接收新对象:

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

     [self dismissViewControllerAnimated:YES completion:nil];
}

The code above depends of if your tableViewArray object is mutable or not. 上面的代码取决于tableViewArray对象是否可变。 If it's not, you can change the type of the object argument in the protocol method to an inmutable array object and just assign tableViewArray to the new array. 如果不是,则可以将protocol方法中的object参数的类型更改为不可变的数组对象,只需将tableViewArray分配给新数组。

EDIT: 编辑:

In the prepareForSegue: method don't forget to set the delegate: prepareForSegue:方法中,不要忘记设置委托:

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

First of all make sure you alloc , init your tableViewArray in HomeViewController 首先确保您alloc ,在HomeViewController init tableViewArray

Second , In this line 二,在这行

HomeViewController *homeVC = [[HomeViewController alloc] init]

you are creating a new reference to your HomeViewController which is not correct, you need to pass correct reference, possibly creating HomeViewController variable in your OutsideViewController 您正在创建对HomeViewController的不正确的新引用,您需要传递正确的引用,可能在OutsideViewController创建HomeViewController变量

Even though you correctly do first and second suggestion you will still see an empty tableview because you dont reload the tableview, somehow you need to fire [self.tableview reloadData]; 即使您正确地执行了第一和第二个建议,您仍然会看到一个空的tableview,因为您没有重新加载tableview,但是您还是需要触发[self.tableview reloadData]; method. 方法。

That means; 那意味着 you need to learn Delegate or NSNotifications pattern to communicate between child->parent scenarios 您需要学习DelegateNSNotifications模式才能在子级->父级方案之间进行通信

How do I set up a simple delegate to communicate between two view controllers? 如何设置一个简单的委托以在两个视图控制器之间进行通信?

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

For your question just create a delegate in your Outside ; 对于您的问题,只需在您的Outside创建代表; in your OutsideViewController.h 在您的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

in your OutsideViewController.m 在您的OutsideViewController.m中

@synthesize delegate;


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

in your HomeViewController.h 在您的HomeViewController.h中

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

in your HomeViewController.m 在您的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];
}

Another Solution Would be 另一个解决方案是

Change your view stack to this: 将您的视图堆栈更改为此:

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

and apply rdurand 's answer 并应用rdurand的答案

and add this to your HomeViewController : 并将其添加到您的HomeViewController中:

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

In this solution since you are just push-pop viewcontrollers in a nabigation stack viewDidAppear will be called in HomeViewController everytime when you pop OutsideViewController. 在此解决方案中,由于您只是在栈堆栈中的推入式视图控制器,因此每次您在弹出OutsideViewController时,都会在HomeViewController中调用viewDidAppear

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

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