开发者

NSTimer questions

So I have two problems but both are related.

  1. I created a "animation" that moves a progress view when a button is clicked by using NSTimer. This animation works fine the first couple times the button is clicked but after that it starts speeding up the process, practically skipping from the initial start of the NSTimer loop to the end of the NSTimer loop. I was wondering if anyone has ever heard of this issue and/or knows a solution?

  2. I created the same thing in question 1 but in a UItableViewCell and the NSTimer loop is activated when the edit button is pressed. The edit button activates a function that has this [self.tableView2 setEditing:NO animated:YES]; and the NSTimer scheduledTimerWithInterval ... (The progress view animation). The issue here is that it the setEdit animation no longer animates it just pops into place. Once again, does anyone know of a solution for this?

Here is the code for question 2 (Both the code for the questions are very similar so if you can spot the problem here then it is likely I can use that solution to fix them both):

-(void)editTable{
    [self.tableView2 setEditing:YES  animated:YES];
    iCount = 8;
    iCount2 = 257;
    forwardProgress = YES;
    animationFlag = YES;
    myTimer = [NSTimer scheduledTimerWithTimeInterval:0.001f target:self selector:@selector(increaseAmount) userInfo:nil repeats:YES];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(cancelEdit)];
}

-(void)cancelEdit{
    [self.tableView2 setEditing:NO  animated:YES];
    forwardProgress = NO;
    animationFlag = YES;
    iCount = 38;
    iCount2 = 227;
    myTimer = [NSTimer scheduledTimerWithTimeInterval:0.001f target:self selector:@selector(increaseAmount) userInfo:nil repeats:YES];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit target:self action:@selector(editTable)];
}

-(void)increaseAmount{
    float max = 38.0f;
    float max2 = 257.0f;
    float min2 = 227.0f;
    float min = 8.0f;
    if (animationFlag == YES) {
        if (forwardProgress == YES) {
            if (iCount <= max) {
                iCount++;
                // NSLog(@"iCount = %i", iCount);
            }
            if (iCount2 >= min2) {
                iCount2--;
                // NSLog(@"iCount2 = %i", iCount2);
            }
            if (iCount <= max) {
                [tableView2 reloadData];
            }
            if (iCount2 >= min2) {
                [tableView2 reloadData];
            }
            if (iCount == max) {
                 animationFlag = NO;
            }
            newFrame  = CGRectMake(iCount, 33.0f, iCount2, 11.0f);
            [tableView2 reloadData];
    开发者_StackOverflow中文版    }else{
            if (iCount >= min) {
               iCount--;
               NSLog(@"iCount = %i", iCount);
            }
            if (iCount2 <= max2) {
                iCount2++;
                NSLog(@"iCount2 = %i", iCount2);
            }
            newFrame = CGRectMake(iCount, 33.0f, iCount2, 11.0f);

            if (iCount >= min) {
                [tableView2 reloadData];
            }
            if (iCount2 <= max2) {
                [tableView2 reloadData];
            }
            if (iCount == min) {
                animationFlag = NO;
            }
        }
    }

}


Any timer invalidates itself when it has finished unless it has repeats:YES. If that's the case, you need to invalidate it yourself at some point, ideally when all your conditions are met. In your case I think you'd want it when you're setting animationFlag == 0 (I presume that's when you want the timer to stop firing). Use something like this:

 if ([myTimer isValid]) {
    [myTimer invalidate];
    myTimer = nil;

You also need to place that code in editTable at the beginning. That way, if a timer was running and someone started it again, it would first reset, and then begin again.Otherwise you have multiple timers all firing increaseAmount. You also need it anytime the user cancels the timer.


  1. You probably have to invalidate the timer from your first animation. I suspect that you have two timers running and therefore the speed of the animation is doubled.

  2. This is probably because of the reloadData call in your timer callback. A tableview cannot reload and animate at the same time.


I believe rgeorge is correct;

You don't get rid of the "myTimer" when you stop your animation. So even though you may not see the animation any more, increaseAmount is still being called over and over. Change the method to something like this:

-(void)increaseAmount:(NSTimer*)Timer;

Then, when you're done with increase amount, make sure to turn off the timer from within increaseAmount.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜