从第二个视图控制器ios将对象添加到基本视图控制器中的NSMutableArray

时间:2013-06-22 02:17:27

标签: ios objective-c uiviewcontroller segue sharing

我一直在寻找如何做到这一点。我有2 View Controllers。从根View ControllerViewControllerA - 这是一个表视图控制器),您可以转到第二个视图控制器(ViewControllerB)。

ViewControllerB中,有两个字段:contacts&的TextBody。用户完成后,可以单击“添加”。然后,这将返回ViewControllerA。我现在要做的是,每次发生这个过程时,刚刚添加的用户ViewControllerB的所有信息都会进入ViewControllerA的单元格。然后,用户可以根据需要添加任意数量的单元格。

然而,我不能做的是通过视图控制器获取信息。我整个上午一直在寻找使用app delegate,singletons ??,协议,共享属性等等!但我仍然被卡住了。

我想要做的但不是每次用户点击ViewControllerB上的“添加”,联系人和&文本被放入一个数组中。然后将此数组放入另一个数组中,该数组包含用户创建的所有较小数组?如果您有想法或类似/示例代码或教程的链接,那将非常感激!

5 个答案:

答案 0 :(得分:2)

使用委托方法尝试以下

Download Sample Project with XIBs

Download Sample Project With Storyboard

<强> ParentViewController.h

#import <UIKit/UIKit.h>

@interface ParentViewController : UIViewController {    
    NSMutableArray *dataArray;
}
- (void)passData:(NSMutableArray *)array;
@end

<强> ParentViewController.m

#import "ParentViewController.h"
#import "ChildViewController.h"

@implementation ParentViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Initialise the mutable array.
    dataArray = [[NSMutableArray alloc] init];
}

- (IBAction)btnGoToSecondView:(id)sender {
    ChildViewController *secondVC = [[ChildViewController alloc] initWithNibName:@"ChildViewController" bundle:nil];
    secondVC.delegate = self;
    [self presentViewController:secondVC animated:YES completion:nil];
}

- (void)passData:(NSMutableArray *)array {
    [dataArray addObject:array];
    NSLog(@"Data Passed = %@",dataArray);
}
@end

<强> ChildViewController.h

#import <UIKit/UIKit.h>
#import "ParentViewController.h"

@class ParentViewController;

@interface ChildViewController : UIViewController {    
    NSMutableArray *tempArray;
}

@property (strong, nonatomic) IBOutlet UITextField *txtContact;
@property (strong, nonatomic) IBOutlet UITextField *txtTextBody;
@property(nonatomic, assign) ParentViewController *delegate;
@end

<强> ChildViewController.m

@implementation ChildViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Initialise the mutable array.
    tempArray = [[NSMutableArray alloc] init];
}

- (IBAction)btnPassDataBack:(id)sender {
    if([self.delegate respondsToSelector:@selector(passData:)]) {

        [tempArray addObject:_txtContact.text];
        [tempArray addObject:_txtTextBody.text];

        [self.delegate passData:tempArray];
    }
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (void)viewDidUnload {
    [self setTxtContact:nil];
    [self setTxtTextBody:nil];
    [super viewDidUnload];
}
@end

使用Storyboard

如果你正在使用故事板,那么创建一个ParentViewController segue ChildViewController并在我的样本中给它一个identifier showChildView

然后使用以下代码设置委托

// Calling the segue to go to the child view and setting up the delegate.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showChildView"]) {
        ChildViewController *childVC = segue.destinationViewController;
        childVC.delegate = self;
    }
}

然后关闭回ParentViewController使用以下代码(来自我的样本)

- (IBAction)btnPassDataBack:(id)sender {
    if([self.delegate respondsToSelector:@selector(passData:)]) {

        [tempArray addObject:_txtContact.text];
        [tempArray addObject:_txtTextBody.text];

        [self.delegate passData:tempArray];
    }
    [self.navigationController popToRootViewControllerAnimated:YES];
}

答案 1 :(得分:1)

我建议使用NSMutableDictionary的单例实例,因为它们已经多次保存了您的确切情况(包括自定义框架和UITabBarControllers)。这是我目前用来实现单例的一个例子。这种方法也是ARC安全的

mySingleton.h

#import <Foundation/Foundation.h>

@interface mySingleton : NSObject {

}
+ (NSMutableDictionary *) myMutableDict;

@end

mySingleton.m

#import "mySingleton.h"

@implementation mySingleton

+ (NSMutableDictionary *)myMutableDict
{
    static NSMutableDictionary *singletonInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singletonInstance = [[NSMutableDictionary alloc]init];

    });
    return singletonInstance;
}

@end

只要在所有视图控制器中包含mySingleton.h,您就可以通过[mySingleton myMutableDict]访问数据。例如:[[mySingleton myMutableDict] setObject:myObject forKey:myKey];

祝你好运!

答案 2 :(得分:1)

如果信息真的是“全局” - 它在整个应用程序中只有一个实例 - 那么你应该像DB80Buckeye建议的那样创建一个单例。

如果信息是真正属于ViewController1的东西,并且你希望它在ViewController2中被修改(即ViewController2实际上是ViewController1的一部分,它恰好在另一个屏幕上),那么你应该将它作为一部分传递给它ViewController2的构造函数。

-(void)view_controller_1_that_push_view_controller_2_onto_the_stack {
     ViewController2* vc2 = [[ViewController2 alloc] initWithInformation:your_information];
     [self.navigationController pushViewController:vc2 animated:YES];
}

@interface ViewController2 

-(id)initWithInformation:(YourInformationClass*)info;

@end

另一种方法是使用通知。

答案 3 :(得分:1)

这里有两种方法。执行此操作的标准模式是委派。你不需要单身人士。 ViewControllerA管理并列出您的数据。 ViewControllerB不需要知道所有这些数据,因此没有理由通过单例等公开它。

ViewControllerB的头文件中创建委托协议。像这样:

@protocol ViewControllerBDelegate
- (void)addContact:(NSString *)contact withBody:(NSString *)textBody;
@end

现在,指定ViewControllerA将在其标头中实现委托协议:

@interface ViewControllerA : UIViewController <ViewControllerBDelegate>

不要忘记在ViewControllerB.h标题的顶部导入ViewControllerA

ViewControllerA的实现中,实现您在协议中指定的委托方法:

- (void)addContact:(NSString *)contact withBody:(NSString *)textBody {
    [self.someArray addObject:[[SomeObject alloc] initWithContact:contact body:textBody]];
    [self.tableView reloadData];
}

这显然只是一个例子 - 不确定你是如何管理你的数据结构的,并且最好在有意义的地方插入单元格。

ViewControllerB的标题中声明委托引用:

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

当您出示ViewControllerB时,请将ViewControllerA设为代表。

ViewControllerB *b = [[ViewControllerB alloc] init...];
b.delegate = self;

ViewControllerB中的添加按钮触发的选择器中,在将视图控制器从导航堆栈中弹出之前回调代理:

[self.delegate addContact:contact withBody:text];

其中contacttext是用户输入的值。

也可以使用块而不是委托,但原理是相同的 - 让第二个视图控制器只负责输入,在您的情况下,并将其传递回管理数据的视图控制器。 / p>

答案 4 :(得分:1)

或者代表建议使用以下内容: ViewControllerA.h:

 @property (nonatomic, strong) ViewControllerB* viewControllerB; 

在ViewControllerA.m中

if (!self.viewControllerB)
{
     self.viewControllerB = [[ViewControllerB alloc] initWithNibName: @"ViewControllerBr"                                                                                                 bundle: nil];      
}
[self.navigationController pushViewController: self.viewControllerB
                                     animated: YES];

...

- (void) viewWillAppear: (BOOL) animated

   if (self.viewControllerB)
   {
       NSString* contact = self.viewControllerB.contact;
       NSLog(@"%@", contact);
   } 

...