我正在尝试做一些非常简单的事情:当应用程序从后台变为活动状态时,更新我(一个也是唯一的(视图控制器上的一些标签(例如,为了简单起见,使用当前时间(即使在我的情况下,我正在更新电话参数,例如呼叫状态等,但这无关紧要((。
老实说,我确信一旦我调用viewDidLoad
,此方法中的代码就会再次运行,因此我的所有标签都将是最新的。但这不会发生,除非我杀死应用程序并重新启动它,所以我在 applicationDidBecomeActive
下的应用程序委托中所做的,我调用了我的视图控制器方法:
ViewController *vc = [[ViewController alloc] init];
[vc refreshCalls];
它确实执行此代码,但标签没有任何变化。执行此操作时,我还显示了一个UIAlertView
,该确实具有更新的信息,但没有标签。
我该如何解决这个问题?任何想法将不胜感激。
这是我的应用程序委托应用程序DidBecomActive方法:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
ViewController *vc = [[ViewController alloc] init];
[vc refreshCalls];
}
视图控制器中的refreshCalls
方法:
-(void) refreshCalls {
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// display in 12HR/24HR (i.e. 11:25PM or 23:25) format according to User Settings
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSString *currentTime = [dateFormatter stringFromDate:today];
NSLog(@"User's current time in their preference format:%@",currentTime);
UIAlertView *alert1 = [[UIAlertView alloc] initWithTitle:@"TIME" message:currentTime delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil , nil];
[alert1 show]; --> does show an update time
myLabel.text = currentTime;
[self.view addSubview:myLabel]; --> nothing happens, stays the last time
}
首先,你不应该称ViewDidLoad
.它被召唤给你,就像applicationDidBecomeActive
.
现在,答案是:
正在发生的事情是,您正在新ViewController
而不是现有上调用 refreshCalls
方法,您可能在应用程序委托中的某个位置创建了该方法。当您第一次创建ViewController
时,您可能将其视图添加到UIWindow
中。
然后,当您在 applicationDidBecomeActive
中创建新ViewController
并对其调用 refreshCalls
时,它会像应有的方式更新,但其视图不会显示在屏幕上,因为您没有将其添加到 UIWindow
中。
尝试在appDelegate
中找到您最初创建ViewController
并将其分配给属性的位置。然后,不是在 applicationDidBecomeActive
中创建新ViewController
,而是获取现有并对其调用 refreshCalls
方法。
的观点中已经有一个myLabel
,您可能不应该添加另一个。也许您可以尝试使用像self.myLabel
这样的@property
,并在每次要更新其文本时调用self.myLabel.text = currentTime;
。(没有addSubview
再次或东西..(
ViewController
的viewDidAppear:animated
中更新标签,而不是使用applicationDidBecomeActive
。像这样:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self refreshCalls];
}
混淆,我决定在上一个答案的基础上创建另一个答案。
基本思想是在UIApplication
类中保留订阅者列表,并在收到UIApplicationDelegate
事件时通知他们。这是如何做到的。
步骤 1
在派生类标头UIApplication
添加静态方法的定义以管理列表:
+ (void)addDelegate:(id <UIApplicationDelegate>)delegate;
+ (void)removeDelegate:(id <UIApplicationDelegate>)delegate;
我正在使用UIApplicationDelegate
因为它是一种"自然"的解决方案。但是,您可以定义自己的协议或扩展UIApplicationDelegate
。
步骤 2
在应用程序类中添加实现。首先为列表添加定义,介于最后 #import
和 @implementation
之间。
static NSMutableArray *_delegates;
在@implementation
内部,我们添加了静态方法主体和初始化:
+ (void)initialize {
_delegates = [[NSMutableArray alloc] init];
}
+ (void)addDelegate:(id <UIApplicationDelegate>)delegate {
[_delegates addObject:delegate];
}
+ (void)removeDelegate:(id <UIApplicationDelegate>)delegate {
[_delegates removeObject:delegate];
}
对于需要通知订阅者的每种UIApplicationDelegate
方法,请添加类似于以下示例的代码:
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSEnumerator *enumerator = [_delegates objectEnumerator];
id delegate;
while (delegate = [enumerator nextObject]) {
if ([delegate respondsToSelector:@selector(applicationDidBecomeActive:)]) {
[delegate applicationDidBecomeActive:application];
}
}
}
步骤 3
在您的UIViewController
(或任何其他类(中添加代码以订阅、取消订阅和处理通知。不要忘记导入您的UIApplication
类标头。
订阅可以在您的 init 方法中设置,也可以在viewDidLoad
内部设置UIViewController
也很好。
[MyAppDelegate addDelegate:self]; // your class should implement UIApplicationDelegate
不要忘记取消订阅,否则可能会发生坏事!在您的 dealloc 方法中添加它或用于viewDidUnload
内部的UIViewController
就可以了。
[MyAppDelegate removeDelegate:self];
最后添加您需要获得有关 ex 的通知UIApplicationDelegate
方法:
- (void)applicationDidBecomeActive:(UIApplication *)application {
// add your notification handling code here
}