Search code examples
iosanimationuipickerview

Prolong UIPickerView [selectRow: inComponent: animated:]'s animation


I'm using a UIPickerView to display random numbers. The user can press a button, and thus trigger a random selection of a number inside the UIPickerView.

It does not matter how many objects or numbers are being displayed inside the UIPickerView, when I call the method:

[self.picker selectRow:randomRow inComponent:0 animated:YES];

It always gets animated with the same time interval.

Is there any option or method to prolong the animation time interval of above method?

I have tried placing it in an animation block:

[UIView beginAnimations:@"identifier" context:nil];
// code
[UIView commitAnimations];

but this seems to be a dead end.

I have also tried executing it in a completion blocks:

// 0.34f is the approximate defualt apple animation
[UIView animateWithDuration:0.34f animations:^{

[self.picker selectRow:randomRow inComponent:0 animated:YES];

} completion:^(BOOL finished) {

[UIView animateWithDuration:0.34f animations:^{

    [self.picker selectRow:randomRow inComponent:0 animated:YES];

} completion:nil];
}];

Any help would be appreciated.


Solution

  • I made a project and play for a while till I find out this tricky solution. It base on the method performSelector:afterDelay

    Here is the touch up inside code of your button:

    - (void)click:(id)sender
    {
        int randomRow = <>;//Your random method
    
        int currentRow = [_picker selectedRowInComponent:0];
    
        int i = 0;
        while(1)
        {
            i++;
            NSString *rowToSelectString = [NSString stringWithFormat:@"%d", currentRow];
            NSDictionary *rowToSelectDictionary = @{@"row":rowToSelectString};
    
            if(randomRow < currentRow)
            {
                // Go backward
                currentRow--;
            }
            else
            {
                // Go forward
                currentRow++;
            }
    
    
            [self performSelector:@selector(selectRowInPicker:) withObject:rowToSelectDictionary afterDelay:i*0.1];//Change the delay as you want
    
            if(currentRow == randomRow)
            {
                break;
            }
        }
    }
    

    And the trick:

    -(void)selectRowInPicker:(NSDictionary *)rowToSelectDictionary
    {
        NSInteger row = [[rowToSelectDictionary objectForKey:@"row"] integerValue];
        [_picker selectRow:row inComponent:0 animated:YES];
    }
    

    This work well for me. Tell me if you're having problem with it.