views:

115

answers:

1

Hello everybody, And thank you in advance for your attention. I am trying to achieve a little animation effect in my simple application, using this time an UIPickerView object.

Basically, when a certain event occurs, I wish my picker view to animate itself selecting its last row (with animation, of course) and immediately after (without any further user interaction) its first row (with animation, of course). This, to give an 'application got crazy' effect which is supposed to be really really witty, I guess.

Therefore my code was:

[myPicker selectRow:[myPicker numberOfRowsInComponent:0]-1 inComponent:0 animated:YES];
[myPicker selectRow: 0 inComponent:0 animated:YES];

And what I got is that the picker will execute only the second instruction no matter the row specified within it. It seems to ignore the first one.

I thought it could be for some 'clever' function of the compiler which notes that two following instructions perform an assignment to the same variable, therefore is better to ignore the first one (not considering the 'ANIMATED' factor). I don't know if it is the case but I tried to move these two instructions within two if statements based on value of some parameter, trying this way to fool the compiler (which cannot know at compile time the value of that parameters, therefore it is not supposed to perform such an optimization). It didn't work, either because I am completely out of trace or because the compiler is far more clever than me. I even thought it could be a problem of delays and correct sequence of events therefore I tried to rewrite the code as follow

-(void) setPickerRowToLastRow;
 {
     [myPicker selectRow:[myPicker numberOfRowsInComponent:0]-1 inComponent:0 animated:YES];
 }
 -(void) setPickerRowToFirstRow;
{
    [myPicker selectRow:0 inComponent:0 animated:YES];
}
                      .....
[self performSelector: @selector(setPickerRowToLastRow)
                     withObject: nil
                     afterDelay: 1];
[self performSelector: @selector(setPickerRowToFirstRow)
               withObject: nil
               afterDelay: 1];

And it didn't work: the picker still performs just the second action and it will move just once.

And now the question(s):

Why does the picker move just once?

How can I reach my goal (even if maybe a bit trivial)?

+2  A: 

This has nothing to do with the compiler. It's not that clever.

The reason only one animation is performed is that the animation doesn't start "at once" but on the next run loop (more about which here). At that point the animation will start, using the latest values sent to the picker.

Using performSelector:withObject:afterDelay: should work, and the reason it doesn't is probably that you put 1 as the delay for both invocations. Set it to 0 on the first and 2 (for example) on the second, and it should work.

Felixyz
I just tried and doing as you told, it works (well..I wasn't that far from the solution). It seems to work with any couple of delay parameters where the second is higher than the first one. Your answer solved my problem, thank you very much.