Change Text When UIImage in a UIImageView Animation Changes - ios

In my app, I need to set up an animation that will run on repeat until I perform an action on it. I want both an image to change, and text change along with it. I am trying now the suggested key frame animations, but it is only showing the last change and no repeats. I have done some searches and looking at the documentation, but I'm definitely still missing something.
It was my understanding that the animateKeyframesWithDuration is measured in seconds, while relative start and relative duration are 0 - 1 in value, so I set each to be 0.2, as there are 5, and 0.2 is exactly a fifth. What am I doing wrong? All of the NSLogs fire, but none of the events actually change, other than the final one.
[UIView animateKeyframesWithDuration:70 delay:0 options:UIViewKeyframeAnimationOptionRepeat animations:^{
[UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.2 animations:^{
NSLog(#"a1");
self.eventsText.text = nil;
theImageView.image = [UIImage imageNamed:#"welcome.png"];
}];
[UIView addKeyframeWithRelativeStartTime:0.2 relativeDuration:0.2 animations:^{
NSLog(#"a12");
theImageView.image = [UIImage imageNamed:#"pleasepray.png"];
self.eventsText.text = #"Test2";
}];
[UIView addKeyframeWithRelativeStartTime:0.4 relativeDuration:0.2 animations:^{
NSLog(#"a13");
theImageView.image = [UIImage imageNamed:#"comingevents.png"];
self.eventsText.text = #"Test3";
}];
[UIView addKeyframeWithRelativeStartTime:0.6 relativeDuration:0.2 animations:^{
NSLog(#"a14");
theImageView.image = [UIImage imageNamed:#"birthdays.png"];
self.eventsText.text = nil;
}];
[UIView addKeyframeWithRelativeStartTime:0.8 relativeDuration:0.2 animations:^{
NSLog(#"a14");
theImageView.image = [UIImage imageNamed:#"ournumbers.png"];
self.eventsText.text = #"Test4";
}];
} completion:nil];

Ok, so here's what I ended up doing. I only have 5 different "slides" that I need to rotate through, and some of them without text. For now, I put text into an Array to simulate what I need. In the future, this will be dynamic, pulled from a server. I then set up an NSInteger property to link everything together, and pull from this array to go along with how long each animation of the images takes.
-(void)announcementsTime {
[self rotatewarmup];
_timer = [NSTimer scheduledTimerWithTimeInterval:14.0 target:self selector:#selector(rotatewarmup )userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer: _timer forMode: NSDefaultRunLoopMode];
}
-(void)rotatewarmup
{
theImageView.hidden = NO;
NSArray *imagesArray = [NSArray arrayWithObjects:
[UIImage imageNamed:#"welcome.png"],
[UIImage imageNamed:#"pleasepray.png"],
[UIImage imageNamed:#"comingevents.png"],
[UIImage imageNamed:#"birthdays.png"],
[UIImage imageNamed:#"contribution2.png"],
nil];
if (self.songNumber == 0) {
if (_firingTime == 4) {
self.eventsText.text = self.allInfo[_firingTime];
theImageView.image = imagesArray[_firingTime];
_firingTime = 0;
}
else {
self.eventsText.text = self.allInfo[_firingTime];
theImageView.image = imagesArray[_firingTime];
NSInteger newFiring = _firingTime + 1;
_firingTime = newFiring;
}
}
else {
self.eventsText.text = #"";
}
}

Related

Program multiple animations for single UIImageView with image change

I need to animate a UIImageView inside my application, and cyclically change the UIImage inside it, making it look like an animated photo slideshow.
Right now I'm using an NSTimer to fire every N seconds the UIImage change and the animation itself:
- (void)viewDidLoad {
// NSArray initialization
NSTimer *timer = [NSTimer timerWithTimeInterval:16
target:self
selector:#selector(onTimer)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
[timer fire];
[super viewDidLoad];
}
This is the onTimer selector code:
- (void) onTimer {
// cycle through max 9 images
if(imageIndex > 8)
imageIndex = 0;
// set the image
[_imageContainer setImage:[images objectAtIndex:imageIndex]];
// reset width and height of the UIImage frame
CGRect frame = [_imageContainer frame];
frame.size.width -= 170.0f;
frame.size.height -= 100.0f;
[_imageContainer setFrame:frame];
// fade in
[UIView animateKeyframesWithDuration:2.0f delay:0.0f options:0 animations:^{
[_imageContainer setAlpha:1];
} completion:^(BOOL finished) {
// image movement
[UIView animateKeyframesWithDuration:12.0f delay:0.0f options:0 animations:^{
CGRect frame = [_imageContainer frame];
frame.size.width += 170.0f;
frame.size.height += 100.0f;
[_imageContainer setFrame:frame];
} completion:^(BOOL finished) {
// fade out
[UIView animateKeyframesWithDuration:2.0f delay:0.0f options:0 animations:^{
[_imageContainer setAlpha:0];
} completion:nil];
}];
}];
imageIndex++;
}
This seem a very raw but "working" way to achieve what I want but I recognize it might not be the ideal way.
Is there any better method to achieve what I'm looking for?
Updated Answer For Fade Animation
- (void)viewDidLoad
{
[super viewDidLoad];
// self.animationImages is your Image Array
self.animationImages = #[[UIImage imageNamed:#"Image1"], [UIImage imageNamed:#"Image2"]];
// make the first call
[self animateImages];
}
- (void)animateImages
{
static int count = 0;
UIImage *image = [self.animationImages objectAtIndex:(count % [animationImages count])];
[UIView transitionWithView:self.animationImageView
duration:1.0f // animation duration
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.animationImageView.image = image; // change to other image
} completion:^(BOOL finished) {
[self animateImages]; // once finished, repeat again
count++; // this is to keep the reference of which image should be loaded next
}];
}

iOS: Changing a UIImageView by pressing an UIButton

I'm making a very simple game. I have a UIButton and an UIImageView. What I'm trying to do is that when the user presses the button, it will change the image to another image and then back to the original image, to simulate an animation (Character moving)
I have this code:
file.m
{
IBOutlet UIImageView *image1;
IBOutlet UIButton *button;
}
-(IBAction)button:(id)sender;
file.h
-(IBAction)button:(id)sender{
[UIView animateWithDuration:1.0f
animations:^{
image1.alpha = 0.1f;
} completion:^(BOOL finished) {
image1.image = [UIImage imageNamed:#"image2.png"];
[UIView animateWithDuration:0.2f
animations:^{
image1.alpha = 1.0f;
} completion:^ (BOOL finished) {
image1.image = [UIImage imageNamed:#"image1.png"];
}];
}];
}
When I open the iOS simulator and press the button, the image dissolves, then reappears and then does the animation. The problem is that I don't want it to dissolve, I just want to show the animation. How do I prevent this from happening? Is it because I'm using alpha properties?
Thank you!
I used the following code to do what I think is what you need (shown here: https://www.dropbox.com/s/vtcyw0n257tgihx/fade.mov?dl=0):
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:#selector(test)];
iv = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 150, 150)];
iv.image = [UIImage imageNamed:#"red"];
[self.view addSubview:iv];
}
- (void)test {
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 0.0f;
} completion:^(BOOL finished) {
iv.image = [UIImage imageNamed:#"blue"];
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 1.0f;
} completion:^ (BOOL finished) {
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 0.0f;
} completion:^ (BOOL finished) {
iv.image = [UIImage imageNamed:#"red"];
[UIView animateWithDuration:1.0f animations:^{
iv.alpha = 1.0f;
} completion:nil];
}];
}];
}];
}
You need to break it down into four parts. First you need to fade the original image out, change it to the second image, fade the second image in, fade the second image out, change back to the original image, then fade it back in.

iOS: why object turns to the start position after animation comletion

)) I'm trying to animate UIButton (two parallel animations: changing of images and moving) as follows, after animation button should be moved, but after completing animation button turns to the start position. Please help to fix it! Thanks in advance!
- (IBAction)bugOneTapped:(id)sender
{
[UIView animateWithDuration:1.0
animations:^{
self.bugOneButton.imageView.animationImages =
[NSArray arrayWithObjects:[UIImage imageNamed:#"bugOne3"],[UIImage imageNamed:#"bugOne2"],[UIImage imageNamed:#"bugOne1"],[UIImage imageNamed:#"bugOne2"],[UIImage imageNamed:#"bugOne3"],[UIImage imageNamed:#"bugOne4"],[UIImage imageNamed:#"bugOne5"],[UIImage imageNamed:#"bugOne4"],nil];
self.bugOneButton.imageView.animationDuration = 0.3;
[self.bugOneButton.imageView startAnimating];
self.bugOneButton.center = CGPointMake(self.bugOnePositionX, self.bugOneButton.center.y - 50);
self.bugOnePositionY = self.bugOnePositionY - 50;
}completion:^(BOOL finished) {
[self.bugOneButton.imageView stopAnimating];
}];
self.bugOneButton.center = CGPointMake(self.bugOnePositionX, self.bugOnePositionY);
}
Remove below line in your code
self.bugOneButton.center = CGPointMake(self.bugOnePositionX, self.bugOnePositionY);
It will fix..
#Genie Wanted said is right,remove code
self.bugOneButton.center = CGPointMake(self.bugOnePositionX, self.bugOnePositionY)
this will reset the button position!
remove this two line
- (IBAction)bugOneTapped:(id)sender
{
[UIView animateWithDuration:1.0
animations:^{
self.bugOneButton.imageView.animationImages =
[NSArray arrayWithObjects:[UIImage imageNamed:#"bugOne3"],[UIImage imageNamed:#"bugOne2"],[UIImage imageNamed:#"bugOne1"],[UIImage imageNamed:#"bugOne2"],[UIImage imageNamed:#"bugOne3"],[UIImage imageNamed:#"bugOne4"],[UIImage imageNamed:#"bugOne5"],[UIImage imageNamed:#"bugOne4"],nil];
self.bugOneButton.imageView.animationDuration = 0.3;
[self.bugOneButton.imageView startAnimating];
self.bugOneButton.center = CGPointMake(self.bugOnePositionX, self.bugOneButton.center.y - 50);
}completion:^(BOOL finished) {
[self.bugOneButton.imageView stopAnimating];
}];
}

IOS: How to detect animation is in progress

This has been asked before but none of the answers are straightforward enough to help little old me.
What exactly does .isAnimating in an UIIimage view do? And how to properly use it?
I am emulating the tap to focus animation in the iPhone camera (yellowish square that pops up and then shrinks when you tap on the preview). That works fine, but I want it to not happen multiple times if it is already animating. This code does the animation but multiple taps gives multiple animationed squares. I suspect it is not just .isAnimating but I'm also doing something else wrong because I tried it with my own boolean too and that fails.
-(void)focusSquarePopUp:(CGPoint)touchPoint;
{
UIImage *focusSquareImage = [UIImage imageNamed:#"yellowFocusSquare"];
UIImageView *tmpView = [[UIImageView alloc] initWithImage:focusSquareImage];
if (!(tmpView.isAnimating))
{
tmpView.center = touchPoint;
tmpView.opaque = YES;
tmpView.alpha = 1.0f;
[self.view addSubview:tmpView];
tmpView.hidden = NO;
// shrink to half size in .3 second
[UIView animateWithDuration:0.3 delay:0 options:0 animations:^{
tmpView.transform = CGAffineTransformMakeScale(.5, .5);
NSLog(#"in animation isAnimating %hhd", tmpView.isAnimating);
} completion:^(BOOL finished) {
// Once the animation is completed hide the view for good
tmpView.hidden = YES;
}];
}
NSLog(#"done animating isAnimating %hhd", tmpView.isAnimating);
[tmpView release];
}
If there is question where this has a solid answer, that would be great.
EDIT - here is the working code.
-(void)focusSquarePopUp:(CGPoint)touchPoint;
{
if (animationInProgress)
return;
animationInProgress = true;
UIImageView *tmpView = [[UIImageView alloc] initWithImage:sp_ui->focus_square];
tmpView.center = touchPoint;
tmpView.opaque = YES;
tmpView.alpha = 1.0f;
[self.view addSubview:tmpView];
tmpView.hidden = NO;
// shrink to half size in .3 second
[UIView animateWithDuration:0.3 delay:0 options:0 animations:^{
tmpView.transform = CGAffineTransformMakeScale(.5, .5);
} completion:^(BOOL finished) {
// Once the animation is completed hide the view for good
tmpView.hidden = YES;
animationInProgress = false;
}];
[tmpView release];
}
I suspect on your code. On your tapping on method focusSquarePopUp: you create new instances of tmpView and focusSquareImage and it adding on self view. That why you found number of animated square equal to number of tap. When you create new instance of those variable then sure isAnimating is firstly you got NO value and it enter animation block code.
Why not you create instance of tmpView and focusSquareImage in .h file of class?? In fact its problem of variable declarations and scope of variables.
Your code should be like this,
Declare instance in animation class (i.e. self.view) .h file
UIImage *focusSquareImage;
UIImageView *tmpView;
Now in .m file viewDidLoad method,
in viewDidLoad
focusSquareImage = [UIImage imageNamed:#"yellowFocusSquare"];
tmpView = [[UIImageView alloc] initWithImage:focusSquareImage];
Your animation method implementation should be,
-(void)focusSquarePopUp:(CGPoint)touchPoint;
{
if (!(tmpView.isAnimating))
{
tmpView.center = touchPoint;
tmpView.opaque = YES;
tmpView.alpha = 1.0f;
[self.view addSubview:tmpView];
tmpView.hidden = NO;
// shrink to half size in .3 second
[UIView animateWithDuration:0.3 delay:0 options:0 animations:^{
tmpView.transform = CGAffineTransformMakeScale(.5, .5);
NSLog(#"in animation isAnimating %hhd", tmpView.isAnimating);
} completion:^(BOOL finished) {
// Once the animation is completed hide the view for good
tmpView.hidden = YES;
[tmpView release];
}];
}
}
Another option of method implementation,
-(void)focusSquarePopUp:(CGPoint)touchPoint;
{
if(!tmpView){
focusSquareImage = [UIImage imageNamed:#"yellowFocusSquare"];
tmpView = [[UIImageView alloc] initWithImage:focusSquareImage];
if (!(tmpView.isAnimating))
{
tmpView.center = touchPoint;
tmpView.opaque = YES;
tmpView.alpha = 1.0f;
[self.view addSubview:tmpView];
tmpView.hidden = NO;
// shrink to half size in .3 second
[UIView animateWithDuration:0.3 delay:0 options:0 animations:^{
tmpView.transform = CGAffineTransformMakeScale(.5, .5);
NSLog(#"in animation isAnimating %hhd", tmpView.isAnimating);
} completion:^(BOOL finished) {
// Once the animation is completed hide the view for good
tmpView.hidden = YES;
[tmpView release];
tmpView = nil;
}];
}
}
}
isAnimating is UIImageView property and it has nothing to do with UIView animation methods
isAnimating is used when you want a UIImageView to alternate between multiple images. For example in the following code the UIImageView display 3 images and alternate between them
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)];
UIImage *image1 = [UIImage imageNamed:#"image1.png"];
UIImage *image2 = [UIImage imageNamed:#"image2.png"];
UIImage *image3 = [UIImage imageNamed:#"image3.png"];
imageView.animationImages = #[image1, image2, image3];
imageView.animationDuration = 1;
NSLog(#"isAnimating %d",imageView.isAnimating); // isAnimating 0
[imageView startAnimating];
NSLog(#"isAnimating %d",imageView.isAnimating); // isAnimating 1
[self.view addSubview:imageView];
Your case is completely different you are using UIView animation blocks and to know if the animation in its block is finished or not you will need to add a Boolean flag instance variable animationFinished and set it to YES in the completion block of the animation

repeat my slide show

i tried to make this slideshow repeat for infinity and didn't work.please help me
-(void)viewDidLoad
{
[super viewDidLoad];
[NSTimer scheduledTimerWithTimeInterval:15 target:self selector:#selector(changeImage) userInfo:nil repeats:YES];
}
-(void)changeImage
{
[UIView transitionWithView:imageView duration:5 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
imageView.image = [UIImage imageNamed:#"6.png"];
} completion:^(BOOL done){
[UIView transitionWithView:imageView duration:5 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
imageView.image = [UIImage imageNamed:#"2.png"];
} completion:^(BOOL done){
[UIView transitionWithView:imageView duration:5 options:UIViewAnimationOptionTransitionFlipFromBottom animations:^{
imageView.image = [UIImage imageNamed:#"3.png"];
} completion:^(BOOL done){
}];
}];
}];
}
Rather than Doing this You can use inbuilt property of UIImageview for animation images.
You can try Something Like,
NSArray *images = [NSArray arrayWithObjects:
[UIImage imageNamed:#"6.png"],
[UIImage imageNamed:#"2.png"],
[UIImage imageNamed:#"3.png"],
nil];
imageView.animationImages = images;
imageView.animationDuration = 1;
imageView.animationRepeatCount = 0; // 0 = nonStop repeat
[imageView startAnimating];
You can get this from example : http://goo.gl/8Gj6m0

Resources