2

我整个早上都在寻找如何做到这一点。我有 2 View Controllers。从根目录View ControllerViewControllerA- 这是一个表视图控制器),您可以推送到第二个视图控制器(ViewControllerB)。

在 中ViewControllerB,有两个字段:contacts 和 textBody。用户完成后,他们可以单击“添加”。这将回到ViewControllerA. 我现在要做的是,每次发生该过程时,来自ViewControllerB用户刚刚添加的所有信息都会进入ViewControllerA. 然后,用户可以添加任意数量的单元格。

然而,我不能做的是跨视图控制器获取信息。我整个上午都在研究使用应用程序委托、单例??、协议、共享属性等!但我仍然卡住了。

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

4

5 回答 5

2

尝试使用委托方法,如下所示

下载带有 XIB 的示例项目

下载带有故事板的示例项目

父视图控制器.h

#import <UIKit/UIKit.h>

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

父视图控制器.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

带故事板

如果您使用的是故事板,则创建一个 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];
}
于 2013-06-22T04:04:08.870 回答
1

我建议您使用 NSMutableDictionary 的单例实例,因为它们已多次将我从您的确切情况中解救出来(包括自定义框架和 UITabBarControllers)。这是我目前用来实现单例的示例。这种方法也是 ARC 安全的

mySingleton.h

#import <Foundation/Foundation.h>

@interface mySingleton : NSObject {

}
+ (NSMutableDictionary *) myMutableDict;

@end

我的单身人士.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];

祝你好运!

于 2013-06-22T02:40:27.207 回答
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

另一种方法是使用通知。

于 2013-06-22T03:11:59.243 回答
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];

wherecontacttext是用户输入的值。

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

于 2013-06-22T03:14:00.740 回答
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);
   } 

...

于 2013-06-22T03:53:20.773 回答