How to nest multiple CA animations? - iphone

How to nest multiple CA animation like UIView animateWithDuration does? For example, I need to animate 6 animations where each next animation goes after previous one. So, with UIView animateWithDuration, every next animation is called from complete block. Does CA allows to use blocks and etc.? If no then how to perform nested sequential animations?

CAAnimation doesn't have a block-based API, but you could use its delegate method animationDidStop:finished: to chain multiple animations.
If you do this a lot, you may want to write your own block-based wrapper for this.

Alternatively to omz's answer, you can set up NSTimer objects to start the successive parts of the animation.
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(legOne:) userInfo:nil repeats:NO];
[NSTimer scheduledTimerWithTimeInterval:4.0 target:self selector:#selector(legTwo:) userInfo:nil repeats:NO];
Where legOne: is a method that does the first part of the animation, etc.

Related

Dynamically generated NSTimers in same UITableview?

I'm trying to implement a timer into a new application. One use case that is likely is to have more than one timer running at a time in the same view updating a UILabel or UIButton title text.
Does anyone have experience of doing this? what approach would you suggest.
The difficulty is when the timers fire off the same selector in short succession.
many thanks in advance
Nick
In .h file declare object:
NSTimer *myTimer1,myTimer2;
In .m file:
myTimer1 = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(nextPhoto) userInfo:nil repeats:YES];
myTimer2 = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:#selector(nextPhoto) userInfo:nil repeats:YES];
After the above invalidate the timers like this:
[myTimer1 invalidate];
[myTimer2 invalidate];
Try it like this.
If you do create repeating timers dynamically, you can run into problems with timer invalidation. I'd suggest you use performSelector:withObject:afterDelay: or performSelectorOnMainThread:withObject:waitUntilDone: methods instead.

How to make a function wait 30 seconds before it starts?

sorry still a newbie in the programming. Basically I have an Uibutton, when that button is pressed it would switch to another view, when it switches to that view, a function which calls a telephone number and sends an SMS text message out starts. What I'm trying to do it make that function wait 30seconds before it starts.
Any idea how to do this please?
just use:
-performSelector:withObject:afterDelay:
YOu can use NSTimer for that.
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:#selector(myTimerMethod:) userInfo:nil repeats:NO];

problem updating uiimageview from NSTimer method

I have problems updating the image of an UIImageView from within a method that is called from a NSTimer.
It works within the viewDidLoad method where I do something like this
[imageView setImage:[self getNextImage]];
later on I do
NSTimer* readTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(readSource:) userInfo:nil repeats:NO];
[readTimer fire];
that works and the readSource method gets called.
There I put this code:
UIImageView* tempImageView = (UIImageView*)[containerView viewWithTag:nextDefragSourcePosition ];
That returns exactly the imageView I want to have -
but the following line does not change the image of the UIImageView
[tempImageView setImage:dataBeingReadImage];
Any ideas ? Thanks in advance.
Heiko
You are aware that you are updating the GUI from a different thread than where the UIImageView is created? You can execute selectors on the main thread to work around this problem.
Just take a look at the performSelectorOnMainThread method. Just call that from the method that gets called when your NSTimer triggers (readSource:) and supply it with the image you want to display. Then just update the UIImageView from THAT selector (not the readSource one) and it SHOULD work.
There really isn't that much code for me to go on.

Please confirm: NSTimer is to repeatedly make an event occur at intervals

I'm trying to make an iOS app. As part of the app, I want a UIScrollView to scroll every X seconds. I believe that I need to use NSTimer. Is this correct?
Yes. You can use NSTimer for this:
float interval = 2.5f; //whatever interval you want
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:interval target:someTarget selector:#selector(someSelector:) userInfo:nil repeats:YES];
Yes. You can use NSTimer to perform either a delayed event or a periodic event. There is a good post on using NSTimer here.
Yes.
NSTimer* theTimer = [NSTimer scheduledTimerWithTimeInterval:X
target:someController
selector:#selector(scrollThatView)
userInfo:nil
repeats:YES];
You don’t need to use an NSTimer—there are other ways to do it—but yes, an NSTimer will allow you to do so.

NSTimer doesn't work without UIApplication?

I have a custom iPhone application which doesn't rely on UIKit in any way (it is not linked to UIKit). This means that I'm not using UIApplication and therefore not calling UIApplicationMain.
The problem is that when I create a timer it never fires. The timer is created like that:
[NSTimer timerWithTimeInterval:10 target:self selector:#selector(updateTime) userInfo:nil repeats:TRUE];
I am suspecting that the problem might be run-loop related as after I finish basic initialization in "main()" , I do this:
NSLog(#"Starting application ...");
applicationInstance = [MyApp alloc];
[applicationInstance setMainLayer:mainLayer];
[NSThread detachNewThreadSelector:#selector(runApplication) toTarget:applicationInstance withObject:nil];
CFRunLoopRun();
I reverse-engineered UIKit and noticed that UIApplication does much more things like registering for system events etc. NSTimer might be relying on one of those things. The other thing I've noticed is that in UIApplication's delegate the thread is the same as in main().
How do I get NSTimer to work properly? If it is run-loop related, can someone point out the error? "CFRunLoopRun()" is used to hang up the main thread so the rest of the application can run. I don't think it is right though.
Edit: I think the run loop needs to be configred. Somehow ...
Your problem is definitely run loop-related; see the NSTimer reference, specifically, the introduction:
Timers work in conjunction with run loops. To use a timer effectively, you should be aware of how run loops operate—see NSRunLoop and Threading Programming Guide. Note in particular that run loops retain their timers, so you can release a timer after you have added it to a run loop.
The solution was pretty simple
NSTimer * timeUpdateTimer = [NSTimer timerWithTimeInterval:1 target:self selector:#selector(updateTime) userInfo:nil repeats:TRUE];
[[NSRunLoop mainRunLoop] addTimer:timeUpdateTimer forMode:NSDefaultRunLoopMode];
Thanks for the tip Shaggy Frog