我有一个简单的应用程序,它在appDelegate中有一个NSTimer对象,可供所有视图访问。应用程序的结构是使用UINavigationController。当我触发NSTimer对象时,我的UILabel正在使用正确的倒计时功能进行更新,但当我返回到rootViewController并返回到倒数计时器视图时,我的UILabel正在使用当前的倒计时时间进行更新,但没有后续更新UILabel发生了。我错过了什么?我已经做过研究确保UILabel对象不是nil,我在viewDidAppear方法上调用该函数,似乎没有任何工作!这是代码:
@interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
@property (nonatomic, retain) NSTimer *countdownTimer;
@implementation AppDelegate
@synthesize countdownTimer;
#import "AppDelegate.h"
enter code here
@interface CountdownTimerViewController : UIViewController {
enter code here
AppDelegate *appdelegate;
}
@property (strong, nonatomic) IBOutlet UILabel *labelCountdownTimer;
@property (strong, nonatomic) IBOutlet UIButton *buttonStartTimer;
@property (strong, nonatomic) IBOutlet UIButton *buttonStopTimer;
- (IBAction)startTimer:(id)sender;
- (IBAction)stopTimer:(id)sender;
@implementation CountdownTimerViewController
@synthesize labelCountdownTimer;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Instatiating Appdelegate
if(!appdelegate)
appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void) viewDidAppear:(BOOL)animated {
if ([appdelegate.countdownTimer isValid]) {
[self countDown];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Button Action Methods
- (IBAction)startTimer:(id)sender {
[self updateCounter];
}
- (IBAction)stopTimer:(id)sender {
[appdelegate.countdownTimer invalidate];
labelCountdownTimer.text = @"00:00:00";
}
int countLimit=30; //seconds
NSDate *startDate;
- (void)countDown {
if([[NSDate date] timeIntervalSinceDate:startDate] >= countLimit) {
[appdelegate.countdownTimer invalidate];
return;
}
else {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = -([currentDate timeIntervalSinceDate:startDate]);
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
NSLog(@"timeString: %@",timeString);
NSLog(@"labelCountdownTimer: %@",labelCountdownTimer);
labelCountdownTimer.text = timeString;
}
}
- (void)updateCounter {
labelCountdownTimer.text = @"00:00:00";
startDate = [NSDate date];
appdelegate.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:@selector(countDown)
userInfo:nil
repeats:YES];
}
答案 0 :(得分:1)
感谢大家的意见。我实际上通过执行一个方法解决了它,它将检索NSTimer在我的AppDelegate中更新的值,因为当我离开视图并返回时,触发NSTimer的方法不再出现在主线程中。只要我的NSTimer有效,此方法就会循环。我还放置了一个延迟,允许UI更新值,然后再次执行该方法。以下是代码,以防有人遇到类似的问题。我从chandan提供的建议中得到了这个想法,谢谢!!
@interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
@property (nonatomic, retain) NSTimer *countdownTimer;
@property (nonatomic, retain) NSString *timeString;
@interface AppDelegate : UIResponder <UIApplicationDelegate> {
}
@property (nonatomic, retain) NSTimer *countdownTimer;
@property (nonatomic, retain) NSString *timeString;
@interface CountdownTimerViewController : UIViewController {
AppDelegate *appdelegate;
}
@property (strong, nonatomic) IBOutlet UILabel *labelCountdownTimer;
@property (strong, nonatomic) IBOutlet UIButton *buttonStartTimer;
@property (strong, nonatomic) IBOutlet UIButton *buttonStopTimer;
- (IBAction)startTimer:(id)sender;
- (IBAction)stopTimer:(id)sender;
@implementation CountdownTimerViewController
@synthesize labelCountdownTimer;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Instatiating Appdelegate
if(!appdelegate)
appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
}
- (void) viewDidAppear:(BOOL)animated {
if ([appdelegate.countdownTimer isValid]) {
[self updateLabel];
} else {
labelCountdownTimer.text = @"00:00:00";
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Button Action Methods
- (IBAction)startTimer:(id)sender {
[self updateCounter];
}
- (IBAction)stopTimer:(id)sender {
[appdelegate.countdownTimer invalidate];
labelCountdownTimer.text = @"00:00:00";
}
int countLimit=30; //seconds
NSDate *startDate;
- (void)updateCounter {
labelCountdownTimer.text = @"00:00:00";
startDate = [NSDate date];
appdelegate.countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/10.0
target:self
selector:@selector(countDown)
userInfo:nil
repeats:YES];
}
- (void)countDown {
if([[NSDate date] timeIntervalSinceDate:startDate] >= countLimit) {
[appdelegate.countdownTimer invalidate];
return;
}
else {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = -([currentDate timeIntervalSinceDate:startDate]);
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
appdelegate.timeString = [dateFormatter stringFromDate:timerDate];
labelCountdownTimer.text = appdelegate.timeString;
}
}
- (void) updateLabel {
if ([appdelegate.countdownTimer isValid]) {
labelCountdownTimer.text = appdelegate.timeString;
[self performSelector:@selector(updateLabel) withObject:nil afterDelay:0.05];
}
}
答案 1 :(得分:0)
像这样输入:
appdelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
实际上不会将UIApplicationDelegate放入AppDelegate类并添加额外的参数。因此,此变量中没有指向计时器的指针。
您需要一种不同的方法来存储计时器指针。
答案 2 :(得分:0)
尝试在主线程上更新UILabel上的文本。有时UILabel中的更新不适用于backgound线程。
- (void) viewDidAppear:(BOOL)animated
{
if ([appdelegate.countdownTimer isValid])
{
[self performSelectorOnMainThread:@selector(countDown) withObject:nil waitUntilDone:NO];
}
}
如果您的appdelegate对象工作正常并且UILabel正在使用当前倒计时时间进行更新,但是没有对UILabel进行后续更新,那么在主线程上应用UI更改
- (void)countDown {
[self performSelectorOnMainThread:@selector(changeCountDownValue) withObject:nil waitUntilDone:NO];
}
- (void)changeCountDownValue
{
if([[NSDate date] timeIntervalSinceDate:startDate] >= countLimit) {
[appdelegate.countdownTimer invalidate];
return;
}
else {
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = -([currentDate timeIntervalSinceDate:startDate]);
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
NSString *timeString = [dateFormatter stringFromDate:timerDate];
NSLog(@"timeString: %@",timeString);
NSLog(@"labelCountdownTimer: %@",labelCountdownTimer);
labelCountdownTimer.text = timeString;
}
}
请仔细检查NSTimer对象。它应该适用于UILabel更新。如果仍有问题,请告诉我。