我希望能够从另一个类刷新视图,但我尝试过的任何工作都没有。我的应用程序是一个标签式应用程序,其中设置了多个选项我在我的ViewController1类中有一个名为refresh的方法,看起来像这个
-(void)TestMe{
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"widgjson" ofType:@"json"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
NSString *responseString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: @"json.txt"];
[responseString writeToFile:docFile atomically:NO encoding:NSUTF8StringEncoding error:Nil];
[self loadView];
[self viewDidLoad];
}
这很好用。当应用程序首次加载时,它会加载不同的json,然后当我单击此按钮时,它会加载一个新的JSON,然后更新视图。这只是暂时的,以测试刷新。但是,如果我尝试从另一个类或AppDelegates ApplicationDidEnterForeground方法调用此方法,则没有任何反应。我试着这样称呼它
-(void)TestMe{
ViewController1 *vc = [[ViewController1 alloc] init];
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"widgjson" ofType:@"json"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
NSString *responseString = [[NSString alloc] initWithData:myData encoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: @"json.txt"];
[responseString writeToFile:docFile atomically:NO encoding:NSUTF8StringEncoding error:Nil];
[vc loadView];
[vc viewDidLoad];
}
那么为什么这个方法不适用于任何其他类。我想要的是能够从另一个类刷新视图或者当应用程序加载时,但似乎找不到任何有用的东西。
如果有人能指出我正确的方向,我将非常感激!
编辑:更新到CLARIFY
好的,我暂时做的不喜欢的就是这个
exit(0);
内部AppDelegates ApplicationDidEnterBackground。这在一定程度上起作用,但不是理想的解决方案。
我希望发生的是,当再次打开应用程序时,AppDelegate会再次运行,从而设置选项卡。从服务器中提取的JSON会影响选项卡的顺序,这就是我需要AppDelegates ApplicationDidFinishLaunching方法再次重新加载自身的原因。
此外,我想知道我可以从应用程序中的其他类中执行此操作。第一次加载我的应用程序时,它会询问用户电话号码,然后将其发送到服务器,然后服务器生成PIN。完成此操作后,我希望AppDelegate方法加载并开始设置选项卡和订单等。
答案 0 :(得分:3)
为防止您的应用程序在后台运行(因此在退出并重新输入时强制重新加载),您可以在info.plist中将UIApplicationExitsOnSuspend
键设置为YES
。
然而,这可能有点激烈。
您当前从应用程序委托中刷新的代码是非首发代码,因为您正在创建视图控制器的新实例,而不是与屏幕上的实例进行通信。
因此,最好不要让您的申请代表参与进程。
相反,您的视图控制器可以将自己注册为UIApplicationDidBecomeActive
通知的观察者,并为自己做任何需要的事情。您通常会在viewDidLoad上注册此通知,并在viewDidUnload上取消注册(因为,根据定义,如果您已卸载视图,则在应用程序恢复时无需刷新它!)。
您将注册如下(在这里使用块,因为它们是未来):
声明一个id为id的ivar来保存观察者对象,在这种情况下我们称之为becomeActiveObserver
。因此,无论您在何处宣布自己的ivars,请添加id becomeActiveObserver
。然后,在viewDidLoad中:
becomeActiveObserver = [[NSNotificationCenter defaultCenter]
addObserverForName:UIApplicationDidBecomeActive
object:nil
queue: nil
usingBlock:^(NSNotification *note){
//put your reloading code in here
[self TestMe];
}];
并在viewDidUnload中删除:
[[NSNotificationCenter defaultCenter] removeObserver:becomeActiveObserver;
您可以按照类似的模式从应用中的任何其他位置获取通知(您自己的或系统的通知)。这是一个比通过app委托传递所有内容更好的设计,因为它涉及更松散的耦合。
答案 1 :(得分:2)
我想clickMe是一个按钮的动作。如果你想在启动时刷新viewcontroller,那么在viewcontroller中添加一个类似于clickme的函数或任何刷新视图并从applicationWillEnterForeground方法调用它的函数,或者你可以试试这个: -
- (void)applicationWillEnterForeground:(UIApplication *)application
{
NSLog(@"app will enter foreground");
[viewController clickMe:NULL];
}
如果应用程序需要,您可以在appDelegate的applicationWillEnterForeground方法中更改该文件。