【问题标题】:Resuming a countdown when poping to root view弹出到根视图时恢复倒计时
【发布时间】:2012-10-31 07:07:01
【问题描述】:

我是 iPhone 开发的新手,正在使用导航控制器和情节提要制作一个倒计时项目。我的应用程序有两个视图。第一个视图只有一个按钮。单击此按钮时,它将转到第二个视图。第二个视图有倒计时对象。我的问题是,当倒计时在第二个视图中运行时,如果我回到第一个视图然后点击按钮转到第二个视图,倒计时不再运行。

代码如下:

view1.h

#import <UIKit/UIKit.h>
#import "view2.h"

@interface view1: UIViewController

-(IBAction)nextpage:(id)sender;

@end

view1.m

@implementation view1


-(IBAction)nextpage:(id)sender
{
    view2 *next=[self.storyboard instantiateViewControllerWithIdentifier:@"secondview"];
    [self.navigationController pushViewController:next animated:YES];
}

@end

view2.h

@interface view2 : UIViewController
{
    IBOutlet UILabel *lbl;
    IBOutlet UITextField *field;

    NSTimer *theTimer;
    NSDate *targetDate;
    NSCalendar *cal;
    NSDateComponents *components;
}

@property (nonatomic,retain) IBOutlet UILabel *lbl;
@property (nonatomic,retain) IBOutlet UITextField *field;
-(IBAction)back_first_view;
@end

view2.m

@implementation view2
@synthesize lbl,field;

- (void)viewDidLoad
{
    cal = [[NSCalendar currentCalendar] retain];
    components = [[NSDateComponents alloc] init];
}

- (IBAction)buttonPressed:(id)sender {

    if (theTimer != nil) {
        return;
    }

    NSString *input = field.text;
    NSArray *timeSplit = [input componentsSeparatedByString:@":"];
    NSUInteger hours =  [[timeSplit objectAtIndex:0] intValue];
    NSUInteger minutes =  [[timeSplit objectAtIndex:1] intValue];
    NSDate *now = [NSDate date];
    NSDateComponents *dateComponents = [cal components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:now];
    [dateComponents setHour:hours];
    [dateComponents setMinute:minutes];

    if (!targetDate) {
        targetDate = [[cal dateFromComponents:dateComponents] retain];
    }
    else {
        targetDate = nil;
        targetDate = [[cal dateFromComponents:dateComponents] retain];
    }

    if ([targetDate timeIntervalSinceNow] > 0) {
        theTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(tick) userInfo:nil repeats:YES];
        [self hideKeyboard];
    }
    else {
        targetDate = nil;
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Cannot countdown because time is before now" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        [alert release];
    }
}

- (void)tick {
    if ([targetDate timeIntervalSinceNow] <= 0) {
        //Checks if the countdown completed

        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Countdown Completed" message:@"YAY! The countdown has complete" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alert show];
        [alert release];

        return;
    }
    components = [cal components:(NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit) fromDate:[NSDate date] toDate:targetDate options:0];

    NSInteger hours = [components hour];
    NSInteger minutes = [components minute];
    NSInteger seconds = [components second];

    NSString *output = [NSString stringWithFormat:@"%i Hours\n%i Minutes\n%i Seconds\n", hours, minutes, seconds];
    lbl.text = output;
}

- (void)hideKeyboard {
    if ([field isFirstResponder]) [field resignFirstResponder];
}

- (IBAction)back_first_view
{
    [self.navigationController popToRootViewControllerAnimated:YES];
}
 @end

【问题讨论】:

    标签: ios xcode nstimer


    【解决方案1】:

    将此方法更改为,

    - (IBAction)nextpage:(id)sender
    {
        [self.navigationController pushViewController:self.next animated:YES];
    }
    

    并将第一行添加到您的 viewDidLoad 或任何此类方法中,

    - (void)viewDidLoad {
           [super viewDidLoad]; //Always keep super call as first call in a method
           self.next = [self.storyboard instantiateViewControllerWithIdentifier:@"secondview"];
        // Do any additional setup after loading the view.
    }
    

    并在 .h 文件中声明下一个 @interface 为,

    @interface view1 : UIViewController
    {
    
    }
    @property (nonatomic, strong) view2 *next;
    

    每次转到下一页时,您都在创建一个新的view2,您需要对其进行更改。

    【讨论】:

    • 感谢您的详细回复,但是当更改方法并添加第一行 viewdidload 时,没有运行 application.error undeclared next in nextpage 方法。
    • 我的错。忘了说,你需要在 .h 文件中声明 view2 *next,因为你现在需要在类的多个方法中使用它。请在 .h 和文件中声明它并检查它。我会更新我的答案。
    • 对不起应用程序没有运行,我想我做不到,如果你看项目,你会找到github.com/fotosit/countdown/downloads网址,谢谢你的帮助
    • 我已经更新了我的答案。请检查一下。我能够运行您的应用程序,并且在进行上述更改后它看起来很棒。检查一下。
    • 非常感谢,我能理解,你的回答对我很有用。
    【解决方案2】:

    因为您使用的是UINavigationController,所以当您从View2 导航回View1 时,View2 实例(以及在其上运行的计时器)被破坏。当您再次导航到 View2 时,它是一个全新的实例。

    要使其按预期运行,您必须以某种方式保持计时器处于活动状态。您可以修改您的应用委托来管理计时器,并让View2 从委托中获取其计时器信息(例如)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      • 1970-01-01
      相关资源
      最近更新 更多