我有一个带标签栏的应用程序和3个不同的View Controller。其中一个imanage是我通过Interface Builder(storyboard)设计的UItableView,我在Inspector中设置了它的视图控制器类 - >检查员身份 - >我在那里设置了类字段,因此,当这个视图控制器被实例化时,我无法控制,因为当用户点击标签栏时,它通过故事板完成。请注意,我是目标C和iOS编程的新手。
我面临的问题,我也在使用远程通知。因此,当我在AppDelgate类的“didReceiveRemoteNotification”中收到远程通知消息时。我需要更新UI界面(在ViewController之上),但问题是我没有从我的AppDelgate类到这个ViewController的引用(指针)(或者我?)。这个ViewController由storyboard实例化,也没有以编程方式实现,否则我可以保留对它的引用。
我做了一些阅读,我知道我可以通过NSNotification进行这种沟通,但我认为这对于一个可能出现的问题来说是一种矫枉过正,因为我是新手,我对iOS并不完全了解发展。
谢谢,
答案 0 :(得分:14)
NSNotifications易于使用,可能是正确的解决方案。
在需要发送消息的app委托中,只需输入:
[[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 :(得分:5)
您的应用代表将有一个指向应用程序窗口的窗口属性。
Window Property具有-rootViewController属性/方法。
对于基于选项卡的应用程序,它会返回TabViewController。
每个TabViewController都有一个方法-(NSArray *)viewControllers,它返回Tab中的ViewControllers。这些按顺序排列。
访问您的应用程序AppDelegate使用[[UIApplication sharedApplication]委托]
一旦你拥有了这些viewcontrollers,你就会知道自从你将它们添加到XIB文件中之后所有这些都是viewController。并且可以执行你的方法
答案 2 :(得分:1)
<强> 1。沟通两个ViewControllers
如果您想要传达两个ViewControllers,您应该使用Apple推荐的@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的answer。但如果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