在我的应用中,我NSTimer
每秒都会更新UILabel。我在UIBackgroundTaskIdentifier
之前添加了NSTimer
,让它在后台运行。
__block UIBackgroundTaskIdentifier bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:updateTimer forMode:NSRunLoopCommonModes];
。 。
-(void)updateTime
{
secondsLeft -= 1;
//NSLog(@"Update time : %d ......",secondsLeft);
dispatch_async(dispatch_get_main_queue(), ^{
_timeLbl.text = [NSString stringWithFormat:@"%d",secondsLeft];
});
}
问题是当我们按下主页按钮app进入后台时,计时器正在运行,但uilabel
没有更新。例如。说,_timeLbl
显示' 45'。现在,如果我按下主页按钮,应用程序将进入后台。 10秒后我点击应用程序图标让应用程序进入前台,在那里我看到' 45' 暂时(小数秒)然后显示35,而不是直接显示35.这意味着标签未使用NSTimer
进行更新。有没有解决方法可以解决这个问题?
谢谢!
答案 0 :(得分:1)
应用代表
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication]setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
}
- (void)applicationWillResignActive:(UIApplication *)application {
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
}];
}
你的CONTROLLER.M
- (void)viewDidLoad {
[super viewDidLoad];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerTick:) userInfo:nil repeats:YES];
}
-(void) timerTick:(NSTimer *)timer1 {
int seconds = pauseTaskTime % 60;
int minutes = (pauseTaskTime - seconds) / 60;
lblTimer.text = [NSString stringWithFormat:@"%d:%.2d", minutes, seconds]
}
完成代码后,请执行以下步骤:
1. Go to your project name.
2. Click Capabilities
3. On your Background Modes.
谢谢
答案 1 :(得分:0)
试试这个
-(void)updateTime {
secondsLeft -= 1;
//NSLog(@"Update time : %d ......",secondsLeft);
dispatch_async(dispatch_get_main_queue(), ^{
timeLbl.text = [NSString stringWithFormat:@"%d",secondsLeft];
});
}
如果在主队列中更改它,它将会更新。我很久以前就面对它,并以这种方式排序。
答案 2 :(得分:0)
尝试使用引用日期而不是实例变量secondsLeft更新标签。
secondsLeft = [[NSDate date] timeIntervalSinceDate:referenceDate]
答案 3 :(得分:0)
在设置标签中的文字后,在方法-(void)updateTime
中写下[_timeLbl layoutIfNeeded];
。
E.g:
-(void)updateTime
{
secondsLeft -= 1;
//NSLog(@"Update time : %d ......",secondsLeft);
_timeLbl.text = [NSString stringWithFormat:@"%d",secondsLeft];
[_timeLbl layoutIfNeeded];
}
layoutIfNeeded检查是否需要更新视图,并在需要时进行更新。我用一个词来刷新视图。
答案 4 :(得分:0)
这对我来说很好。
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
countDown = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timeLeftSinceDate) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:countDown forMode:NSRunLoopCommonModes];
答案 5 :(得分:0)
使用此代码
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
loop = [NSTimer scheduledTimerWithTimeInterval:0.25 target:self selector:@selector(Update) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:loop forMode:NSRunLoopCommonModes];
答案 6 :(得分:0)
您需要使用CLLocation Manager的api进行后台计时器更新,否则NSTimer允许在后台执行10分钟。
试试这个:https://stackoverflow.com/a/38472381/3901620
并将其添加到info.plist
中<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>