2009-06-23 43 views
13

Tôi đang cố gắng tạo đồng hồ đếm ngược đếm ngược, một IBOutlet được kết nối với một trường văn bản, từ 60 giây xuống còn 0. Tôi không chắc chắnĐồng hồ đếm ngược

A. Cách giới hạn lặp lại đến 60 và

B. Làm thế nào để giảm các đếm ngược trong advanceTimer:

- (IBAction)startCountdown:(id)sender 
{ 
    NSTimer *countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self  selector:@selector(advanceTimer:) userInfo:nil repeats:YES]; 
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 
    [runLoop addTimer:countdownTimer forMode:NSDefaultRunLoopMode]; 
} 

- (void)advanceTimer:(NSTimer *)timer 
{ 
    [countdown setIntegerValue:59]; 
} 

Trả lời

19

Bạn đang đi đúng hướng cho đến nay.

Gắn bó với mã bạn đã có, đây là cách advanceTimer phương pháp nên xem xét để làm cho nó hoạt:

- (void)advanceTimer:(NSTimer *)timer 
{ 
    [countdown setIntegerValue:([countdown integerValue] - 1)]; 
    if ([countdown integerValue] == 0) 
    { 
     // code to stop the timer 
    } 
} 

chỉnh sửa: Để làm cho toàn bộ điều nữa hướng đối tượng, và để tránh chuyển đổi từ chuỗi sang số và lại mỗi thời gian, tôi sẽ thay vì làm một cái gì đó như thế này:

// Controller.h: 
@interface Controller 
{ 
    int counter; 
    IBOutlet NSTextField * countdownField; 
} 
@property (assign) int counter; 
- (IBAction)startCountdown:(id)sender; 
@end 

// Controller.m: 
@implementation Controller 

- (IBAction)startCountdown:(id)sender 
{ 
    counter = 60; 

    NSTimer *countdownTimer = [NSTimer scheduledTimerWithTimeInterval:1 
             target:self 
             selector:@selector(advanceTimer:) 
             userInfo:nil 
             repeats:YES]; 
} 

- (void)advanceTimer:(NSTimer *)timer 
{ 
    [self setCounter:(counter -1)]; 
    [countdownField setIntegerValue:counter]; 
    if (counter <= 0) { [timer invalidate]; } 
} 

@end 

Và, nếu bạn có thể tận dụng các ràng buộc, bạn chỉ có thể liên kết các văn bản lĩnh vực của intValue đến counter tài sản của Controller. Điều này sẽ cho phép bạn elminate các IBOutlet trong giao diện lớp học, và setIntegerValue: dòng trong advanceTimer.

cập nhật: Đã xóa mã thêm bộ hẹn giờ vào vòng lặp chạy hai lần. Cảm ơn bạn Nikolai Ruhe và nschmidt vì đã nhận thấy lỗi đó.

Cập nhật: Sử dụng phương pháp setIntegerValue để đơn giản hóa mã, theo nschmidt.

chỉnh sửa: Typo trong định nghĩa về (void) advanceTimer: (NSTimer *) hẹn giờ ... gây khó chịu 'chọn không được công nhận gửi đến dụ' ngoại lệ

+0

Bộ đếm ngượcĐược thêm vào vòng lặp chạy hai lần, điều này sai. –

+0

@Nikolai Ruhe: Cảm ơn bạn đã chỉ ra điều đó. Tôi đã xóa mã không chính xác khỏi các ví dụ của mình. –

+0

Tôi đoán setIntegerValue hiệu quả hơn [NSString stringWithFormat:], vì vậy tôi sẽ không thực hiện "tối ưu hóa" này. Đặc biệt là vì nó không giúp sự rõ ràng của mã. – nschmidt

6

Bạn có thể thêm một biến Ví dụ int _timerValue để giữ giá trị bộ đếm thời gian và sau đó thực hiện như sau. Cũng lưu ý rằng NSTimer bạn đang tạo đã được lên lịch trên vòng lặp chạy hiện tại.

- (IBAction)startCountdown:(id)sender 
{ 
    _timerValue = 60; 
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(advanceTimer:) userInfo:nil repeats:NO]; 
} 

- (void)advanceTimer:(NSTimer *)timer 
{ 
    --_timerValue; 
    if(self.timerValue != 0) 
     [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(advanceTimer:) userInfo:nil repeats:NO]; 

    [countdown setIntegerValue:_timerValue]; 
} 
Các vấn đề liên quan