两个不同的视图控制器如何能够相互通信

我有一个标签栏和3个不同的视图控制器的应用程序。 其中一个iManager我通过Interface Builder(storyboard)devise了一个UItableView,并在Inspector – > inspector identity – >中设置了它的视图控制器类,我在那里设置了类字段,因此,当这个视图控制器得到实例化,因为当用户点击标签栏时,通过故事板完成。 注意,我是新的客观的C和iOS编程。

我面临的问题,我也使用远程通知。 因此,当我在AppDelgate类的“didReceiveRemoteNotification”中收到远程通知消息时。 我需要更新UI接口(上面的ViewController),但问题我没有从我的AppDelgate类(或我?)的这个ViewController的引用(指针)。 这个ViewController的问题,也没有以编程的方式实例化,否则我可以保留对它的引用。

我做了一些阅读,我明白我可以通过NSNotification来进行沟通,但是我认为这可能是一个矫枉过正的问题,可能是因为我是新手,而且我没有完全了解iOS开发。

谢谢,

您的应用程序委托将具有指向应用程序窗口的窗口属性。

Window属性有一个-rootViewController属性/方法。

对于基于标签的应用程序,它会返回给你TabViewController。

每个TabViewController都有一个方法- (NSArray *)viewControllers ,它返回Tab中的ViewControllers。 这些按顺序排列。

访问您的应用程序AppDelegate使用[[UIApplication sharedApplication]委托]

一旦你有这些viewcontrollers你会知道这是所有的viewController,因为你已经将它添加到XIB文件。 并可以执行你的方法

NSNotifications易于使用,可能是正确的解决scheme。

在需要发送消息的应用程序委托中,只需放置:

[[NSNotificationCenter defaultCenter] postNotificationName:@"MyNotification" object:someObjectYouWantToPassCouldBeAppDelegateOrRemoteNotificationObjectOrAnything]; 

在接收消息的视图控制器中,放置:

 -(void)viewDidLoad { [super viewDidLoad]; //you can add as many of these as you like to handle different notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"MyNotification" object:nil]; } -(void)viewDidUnload { //make sure you remove every observer you've added here [[NSNotificationCenter defaultCenter] removeObserver:self name:@"MyNotification" object:nil]; [super viewDidUnload]; } -(void)dealloc { //clean up in case viewDidUnload wasn't called (it sometimes isn't) [[NSNotificationCenter defaultCenter] removeObserver:self]; [super dealloc]; } //use a different handler method for each notification //the method name should match the selector in your observe call in viewDidLoad -(void)handleNotification:(NSNotification *)notification { WhateverClassOfObjectYouWerePassing *object = notification.object; //now you have a reference to the object that was passed from your app delegate } 

对于不同的方法你想调用,只是一个新的通知名称和一个新的处理方法。

1.沟通两个ViewController

如果你想沟通两个ViewController,你应该使用@protocol作为苹果推荐:


ViewController1.h


  @interface ViewController1 : UIViewController<ViewController2Delegate, ViewController2DataSource> @end 

ViewController1.m


 - (IBAction)goToViewController2:(id)sender{ if(viewController2 == nil) { ViewController2 *viewController = [[ViewController2 alloc] initWithNibName:@"View2" bundle:[NSBundle mainBundle]]; viewController2 = viewController; } //... viewController2.delegate = self; viewController2.dataSource = self; [self.navigationController pushViewController:viewController2 animated:YES]; } - (NSString)viewController:(ViewController2 *)controller itemForSomethingAtIndex:(NSInteger)index{ //Send to viewController2 what it needs return [items objectAtIndex: index]; } - (void)viewController:(ViewController2 *)controller didFinishEnteringItem:(NSString *)item{ //Handle the result from the viewController2 NSLog(@"result: %@", item); } 

ViewController2.h


 #import <UIKit/UIKit.h> // Define your delegate methods to return items to the delegate of this viewController @protocol ViewController2Delegate <NSObject> - (void)viewController:(ViewController2 *)controller didFinishEnteringItem:(NSString *)item; @end // Define your dataSource methods to send items from the dataSource to this viewController @protocol ViewController2DataSource <NSObject> - (NSString)viewController:(ViewController2 *)controller itemForSomethingAtIndex:(NSInteger)index; @end @interface ViewController2 : UIViewController @property (nonatomic) id <ViewController2Delegate> delegate; @property (nonatomic) id <ViewController2DataSource> dataSource; @end 

ViewController2.m


 #import "ViewController2.h" @interface ViewController2 () @end @implementation ViewController2 @synthesize //...; - (void)someMethod { //Get someThing from controller1 NSString *item = [dataSource viewController: self itemForSomethingAtIndex:0]; //Return someThing to controller1 [delegate viewController: self didFinishEnteringItem: item]; } 

2.使用viewController与backgroundTask进行通信

如果您想传达后台任务或处理推送通知,请使用@ NickLockwood的答案 。 但是这不会工作,如果viewController它没有加载。 在这种情况下,你应该在AppDelegate中处理:


 //Get the appDelegate instance AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; //And call your custom method to show what it needs [appDelegate customMethod]; 

你的自定义方法应该像下面这样调用控制器:

 AppDelegate > RootController > ViewController1 > ViewController2 > myMethod //do something if viewController2 is visible to the user or push it before do something. //if you use navigation controller, then you need to ask for the position and className