iOS开发 — 解决APP进入后台,定时器倒计时停止计时的问题

最近在做一个电商项目的时候遇到一个问题,就是在订单详情页显示“秒杀抢购倒计时”的时候,当APP退到后台运行一段时间后重新回到前台,倒计时显示的时间为APP退到后台那一瞬间的时间,而不是应当倒计时到的正确的时间,必须要重新进入页面刷新数据后才会显示正确的时间。原因很简单,因为iOS程序进入后台运行,程序很快就会被系统“杀死”,所以定时器会停止执行计时操作。

解决方法:监听APP进入后台、回到前台的通知,在进入后台的时候存一下时间戳,停掉定时器(系统会强制停止定时器),再在进入前台时计算时间差。若剩余的时间大于时间差,就减去时间差,否则赋值剩余时间为0。

具体核心代码如下所示:

@interface OrderDetailsHeaderView ()

@property (nonatomic,strong) NSTimer *timer;

@property (nonatomic,assign) NSInteger seconds;

@property (nonatomic,assign) NSTimeInterval timestamp;

@end

@implementation OrderDetailsHeaderView

/**
 01 退款成功
 02 退款中
 03 已完成
 04 已支付
 05 已取消
 06 待付款
 */
#pragma mark - setter
- (void)setTheOrderModel:(TheOrderModel *)theOrderModel
{
    _theOrderModel = theOrderModel;
    if ([theOrderModel.status isEqualToString:@"04"]) {
        self.stateLbl.text = @"已付款";
        
        self.invoiceBtn.hidden = NO;
        self.repurchaseBtn.hidden = NO;
    }else if ([theOrderModel.status isEqualToString:@"05"]) {
        self.stateLbl.text = @"已取消";
        
        self.repurchaseBtn.hidden = NO;
    }else if ([theOrderModel.status isEqualToString:@"06"]) {
        self.stateLbl.text = @"待付款";
        
        //开始监听App进入前后台通知
        [self observeApplicationActionNotification];
        
        //秒杀倒计时按钮
        self.payBtn.hidden = NO;
        [self.payBtn seckillCountDown:theOrderModel.leftPayTime.intValue normalTitle:@"" countDownTitle:@"去支付" normalBGColor:COLOR(clearColor) countDownBGColor:COLOR(clearColor)];
        self.timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(countBack) userInfo:nil repeats:YES];
        [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
        self.seconds = theOrderModel.leftPayTime.intValue;
        
        self.cancelOrderBtn.hidden = NO;
    }
}

#pragma mark - 监听App进入前后台通知
- (void)observeApplicationActionNotification
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil];
}

- (void)applicationDidEnterBackground
{
    self.timestamp = [NSDate date].timeIntervalSince1970;
    self.timer.fireDate = [NSDate distantFuture];
}

- (void)applicationDidBecomeActive
{
    NSTimeInterval timeInterval = [NSDate date].timeIntervalSince1970 - self.timestamp;//计算时间差
    self.timestamp = 0;
    
    if (self.seconds - timeInterval > 0) {
        self.seconds = self.seconds - timeInterval;
        self.timer.fireDate = [NSDate date];
        //重新显示商品秒杀倒计时
        [self.payBtn removeFromSuperview];
        self.payBtn = [HELPER buttonWithSuperView:self andNormalTitle:@"" andNormalTextColor:THEME_COLOR andTextFont:14 andNormalImage:nil andCornerRadius:15 backgroundColor:COLOR(whiteColor) addTarget:self action:@selector(toPayFor:) forControlEvents:UIControlEventTouchUpInside andMasonryBlock:^(MASConstraintMaker * _Nonnull make) {
            make.centerY.equalTo(self);
            make.width.equalTo(@100);
            make.right.equalTo(self.cancelOrderBtn.mas_left).offset(-10);
            make.height.equalTo(@30);
        }];
        self.payBtn.layer.borderColor = THEME_COLOR.CGColor;
        self.payBtn.layer.borderWidth = 1;
        [self.payBtn seckillCountDown:self.seconds normalTitle:@"" countDownTitle:@"去支付" normalBGColor:COLOR(clearColor) countDownBGColor:COLOR(clearColor)];
    }else{
        self.seconds = 0;
        
        [self.timer invalidate];
        self.timer = nil;
        //取消订单
        [self cancelOrder];
    }
}


/**
 timer倒计时
 */
- (void)countBack
{
    self.seconds --;
    if (self.seconds == 0) {
        [self.timer invalidate];
        self.timer = nil;
        
        for (UIView *view in self.subviews) {
            [view removeFromSuperview];
        }
        //取消订单
        [self cancelOrder];
    }
}

#pragma mark - 取消订单操作
- (void)cancelOrder
{
    
}


- (void)dealloc
{
    [self.timer invalidate];
    self.timer = nil;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值