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



我有一个带有选项卡栏和3个不同视图控制器的应用程序。其中一个是我通过界面生成器(故事板)设计的UItableView,我在Inspector->Inspector identity->中设置了它的视图控制器类,并在那里设置了class字段,因此,我无法控制这个视图控制器何时被实例化,就像用户单击选项卡栏时通过故事板所做的那样。注意,我是objective C和iOS编程的新手。

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

我读了一些书,我知道我可以通过NSNotification进行沟通,但我认为这对可能因为我是新手而出现的问题来说是一种过度的处理,因为我对iOS开发没有完全的了解。

谢谢,

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

在需要发送消息的应用程序代理中,只需输入:

[[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
}

对于要调用的不同方法,只需一个新的通知名称和一个新处理程序方法。

您的应用程序Delegate将有一个指向应用程序窗口的窗口属性。

Window属性具有-rootViewController属性/方法。

对于基于选项卡的应用程序,它将返回TabViewController。

每个TabViewController都有一个方法-(NSArray*)viewControllers,它返回选项卡内部的viewControllers。这些按顺序排列。

要访问您的应用程序AppDelegate,请使用[[UIApplication sharedApplication]delegate]

一旦你有了这些视图控制器,你就会知道这些都是哪个视图控制器,因为你已经在XIB文件中添加了它。并且可以执行您的方法

1。通信两个ViewController

如果你想与两个ViewController通信,你应该使用苹果推荐的@协议:


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进行后台任务通信

如果你想交流后台任务或处理推送通知,请使用@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

最新更新