objective-c - Objective-C:完成间隔计时器

标签 objective-c audio timer

我目前正在开发一个间隔计时器,这可能会让您想到Gymboss计时器。比较到此结束。

假设您使用步进器将整个锻炼时间设置为10分钟。您希望每次重复持续1分钟,每次休息30秒。尽管我设法使用“chrono”方法对在锻炼结束时播放的声音进行编码,但我仍在努力使重复或休息结束时播放声音。这是代码 header 的相关部分:

#import <AudioToolbox/AudioToolbox.h>

@interface AutoLayoutViewController : UIViewController <AVAudioPlayerDelegate>
// 1. The three green labels
// Workout's timer
{
    IBOutlet UILabel *workoutTimer;
    NSTimer *workoutCountdown;
}

// Repetition's length
@property (strong, nonatomic) IBOutlet UILabel *repetitionLabel;

// Break's length
@property (strong, nonatomic) IBOutlet UILabel *breakLabel;




// 2. The three steppers

// Stepper for Workout's total length
@property (strong, nonatomic) IBOutlet UIStepper *secondsWorkoutChanged;

// Stepper for Repetition's length
@property (strong, nonatomic) IBOutlet UIStepper *secondsRepetitionChanged;

// Stepper for Break's length
@property (strong, nonatomic) IBOutlet UIStepper *secondsBreakChanged;



// 4. The start button
@property (strong, nonatomic) IBOutlet UIButton *startPauseButton;    

@end

其次,这是实现文件的相关部分:
// 1. Steppers

// Stepper for Workout's length
- (IBAction)secondsWorkoutChanged:(UIStepper *)sender {

    /* User increases value of seconds with stepper. Whenever variable for seconds is equal or greater than 60, the program sets the value of minutes through this division: seconds / 60. */
    seconds = [sender value];
    minutes = seconds / 60;


    /* "If" statement for resetting seconds to 0 in order for the label to look like a watch. REAL number of seconds stored by stepper modulus operated by 60.
     */
    if (seconds > 59) {
        seconds = seconds % 60;
    } // End if.


    [workoutTimer setText: [NSString stringWithFormat:@"%2i : %2i", (int) minutes, (int) seconds]];

}

// Stepper for Repetition's length
- (IBAction)secondsRepetitionChanged:(UIStepper *)sender {

    /* User increase value of secondsBreak with stepper. Whenever variable for secondsBreak exceeds 60, the program sets the value of minutesBreak by dividing the number of seconds with 60. */
    secondsRepetition = [sender value];
    minutesRepetition = secondsRepetition / 60;


    /* "If" statement for resetting secondsBreak to 0 in order for the label to look like a watch. REAL number of seconds stored by stepper modulus operated by 60.
     */
    if (secondsRepetition > 59) {

        secondsRepetition = secondsRepetition % 60;
    } // End if.



    [_repetitionLabel setText: [NSString stringWithFormat:@"%2i : %2i", (int) minutesRepetition, (int) secondsRepetition]];
}



// Stepper for Break's length
- (IBAction)secondsBreakChanged:(UIStepper *)sender {

    /* User increase value of secondsBreak with stepper. Whenever variable for secondsBreak exceeds 60, the program sets the value of minutesBreak by dividing the number of seconds with 60. */
    secondsBreak = [sender value];
    minutesBreak = secondsBreak / 60;



    /* "If" statement for resetting secondsBreak to 0 in order for the label to look like a watch. REAL number of seconds stored by stepper modulus operated by 60.
     */
    if (secondsBreak > 59) {
        secondsBreak = secondsBreak % 60;
    } // End if.



    [_breakLabel setText: [NSString stringWithFormat:@"%2i : %2i", (int) minutesBreak, (int) secondsBreak]];
}




// 3. The buttons

// Method for countdown

- (void)chrono:(NSTimer *)timer
{ // First brace for "chrono" method.

    // Timer loses 1 second when started.
    seconds = seconds -= 1;

    workoutTimer.text = [NSString stringWithFormat: @"%2i : %2i", minutes, seconds];

    // If "statement for including minutes in countdown.
   if (seconds <= 0) {
       if (minutes <= 0) {
           [workoutCountdown invalidate]; // 1: If both minutes and seconds = 0, countdown ends.


           // 1.1: Alarm for end of workout.
           CFBundleRef workoutEnded = CFBundleGetMainBundle();
           CFURLRef soundFileURLRef;
           soundFileURLRef = CFBundleCopyResourceURL(workoutEnded, (CFStringRef) @"alarm_clock_ringing", CFSTR ("wav"), NULL);

           UInt32 soundID;
           AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
           AudioServicesPlaySystemSound(soundID);


           // Reset all steppers when workout ends.
           _secondsWorkoutChanged.value = 0;

           _secondsRepetitionChanged.value = 0;

           _secondsBreakChanged.value = 0;


           // Reset the text displayed in the label to zero.
           [workoutTimer setText:@"00 : 00"];

           [_repetitionLabel setText:@"00 : 00"];

           [_breakLabel setText:@"00 : 00"];


       } // End of "if" statement" for minutes.

       else { // Timer still running
           seconds = 60;
           minutes -= 1;

       } // End of else.

    } // End of all the "if" (general).


} // Last brace for "chrono" method.



 //Start button
-(IBAction) startPauseButton:(UIButton *)sender {
    workoutCountdown = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(chrono:) userInfo:nil repeats:YES];
}

我的问题如下。重复和休息结束后如何播放声音?为了演示的目的,您可以使用“chrono”方法中的声音代码行。

谢谢。

Anh Khoi

最佳答案

尝试在实现文件中实现以下更改:
[注意:我已重新放置了变量的声明语句,并添加了两个新变量secondsValueminutesValue]

@implementation CDTViewController
{
    // instance variables
    int seconds;
    int minutes;
    int secondsRepetition;
    int minutesRepetition;
    int secondsBreak;
    int minutesBreak;
    int secondsValue;
    int minutesValue;
    BOOL startBreakTimer;
    BOOL startRepetitionTimer;
}
- (void)viewDidLoad
{
    [super viewDidLoad];
    startRepetitionTimer = YES;
    startBreakTimer = NO;
}
- (IBAction)secondsRepetitionChanged:(UIStepper *)sender {

    minutesRepetition = [sender value] / 60;
    secondsRepetition = (int)[sender value] % 60;
    secondsValue = secondsRepetition;
    minutesValue = minutesRepetition;
    [_repetitionLabel setText: [NSString stringWithFormat:@"%2i : %2i", (int) minutesRepetition, (int) secondsRepetition]];
}
- (IBAction)secondsBreakChanged:(UIStepper *)sender {

    minutesBreak = [sender value] / 60;
    secondsBreak = (int)[sender value] % 60;
    [_breakLabel setText: [NSString stringWithFormat:@"%2i : %2i", (int) minutesBreak, (int) secondsBreak]];
}
- (void)chrono:(NSTimer *)timer
{
    seconds -= 1;
    secondsValue -= 1;

    if (seconds < 0) {
        seconds = 59;
        minutes -= 1;
        if (minutes < 0) {
            minutes = 0;
        }
    }

    if (secondsValue < 0) {
        secondsValue = 59;
        minutesValue -= 1;
        if (minutesValue < 0) {
            minutesValue = 0;
        }
    }

    workoutTimer.text = [NSString stringWithFormat: @"%2i : %2i", minutes, seconds];

    if (startRepetitionTimer) {
        _repetitionLabel.text = [NSString stringWithFormat: @"%2i : %2i",minutesValue, secondsValue];
        _breakLabel.text = [NSString stringWithFormat: @"%2i : %2i", minutesBreak, secondsBreak];
        if (secondsValue == 0) {
            if (minutesValue == 0) {
                startBreakTimer = YES;
                startRepetitionTimer = NO;
                secondsValue = secondsBreak;
                minutesValue = minutesBreak;

                /* write code to play repetition alarm
             here */
            }
        }
    }
    else if (startBreakTimer) {
        _repetitionLabel.text = [NSString stringWithFormat: @"%2i : %2i",minutesRepetition, secondsRepetition];
        _breakLabel.text = [NSString stringWithFormat: @"%2i : %2i", minutesValue, secondsValue];
        if (secondsValue == 0) {
            if (minutesValue == 0) {
                startBreakTimer = NO;
                startRepetitionTimer = YES;
                secondsValue = secondsRepetition;
                minutesValue = minutesRepetition;

                /* write code to play break alarm
             here */
            }
        }
    }

    if (seconds == 0) {
        if (minutes == 0) {
            [workoutCountdown invalidate];

            // Alarm for end of workout.

            // Reset all steppers when workout ends.
            _secondsWorkoutChanged.value = 0;
            _secondsRepetitionChanged.value = 0;
            _secondsBreakChanged.value = 0;

            // Reset the text displayed in the label to zero.
            [workoutTimer setText:@"00 : 00"];
            [_repetitionLabel setText:@"00 : 00"];
            [_breakLabel setText:@"00 : 00"];
            return;
        }
    }
}

希望这种逻辑对您有所帮助!

关于objective-c - Objective-C:完成间隔计时器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21178134/

相关文章:

c++ - 在 Objective-C 中使用 C++ 静态库

audio - 在 ffmpeg 中采样准确的音频切片?

iphone - 一个 UIViewController 中的两个 UITableView

iphone - CGContextSaveGState 无效上下文

audio - 如何从RTMP流播放音频?

C# 任务调度器查询

c# - 使用 Timer 测量 Parallel.ForEach 进度意外暂停

f# - 仅在 F# Interactive 中声明变量需要 300 毫秒?

objective-c - 真正的大数字和 Objective-C

c# - 将 mp3 字节数组转换为 float 组以在 Unity 中播放