I want to implement the next situation: step by step change image in uiImageView with UIViewAnimationOptionTransitionCrossDissolve animation.
I've tried the following:
[UIView transitionWithView:imageView
duration:2.0f
options: UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat
animations:^{
imageView.image = [self.images objectAtIndex:self.currentIndex];
self.currentIndex ++;
if (self.currentIndex >2) self.currentIndex = 0;
} completion:^(BOOL finished) {
}];
But this does not even start animation.
The only thing makes it work - use recursion for that purpose:
- (void) switchBckgroundWithIndex: (NSInteger) index imageView: (UIImageView*) imageView
{
if (index >=[self.images count]) index = 0;
#weakify(self)
[UIView transitionWithView:imageView
duration:2.0f
options: UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionTransitionCrossDissolve
animations:^{
#strongify(self)
imageView.image = [self.images objectAtIndex:index];
} completion:^(BOOL finished) {
#strongify(self)
[self switchBckgroundWithIndex:index+1 imageView:imageView];
}];
}
How can i change images repeatedly with those animation effect without using recursion? Please, help me to find solution
I have used this method for animating images in UIImageView
-(void)viewDidLoad
{
[super viewDidLoad];
mutArr=[[NSMutableArray alloc]init];
[mutArr addObject:#"b1#2x.png"];
[mutArr addObject:#"b2#2x.png"];
[mutArr addObject:#"b3#2x.png"];
[mutArr addObject:#"b4#2x.png"];
NSTimer *timerForImage = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(animateImages) userInfo:nil repeats:YES];
}
-(void)animateImages
{
imageCount = imageCount + 1;
NSString *imageName =[NSString stringWithFormat:#"%#",[mutArr objectAtIndex:imageCount]];
if (imageCount==4)
{
imageCount=0;
}
_imgVw.image = [UIImage imageNamed:imageName];
CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[_imgVw.layer addAnimation:transition forKey:nil];
}
#interface abc ()
{
int imgCount;
}
then in -
- (void)viewDidLoad
{
[super viewDidLoad];
imgCount = 0;
[self animateAllImages];
}
- (void)animateAllImages
{
NSArray *animationImages = #[[UIImage imageNamed:#"Image1"], [UIImage imageNamed:#"Image2"],[UIImage imageNamed:#"Image3"],[UIImage imageNamed:#"Image4"]];
UIImage *image = [animationImages objectAtIndex:(imgCount % [animationImages count])];
[UIView transitionWithView:self.animationImageView
duration:0.8f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.animationImageView.image = image;
} completion:^(BOOL finished) {
[self animateAllImages];
imgCount++;
}];
}
Related
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 = #"";
}
}
I want to do continuous animation in 3 imageviews back to back I have use the below code but it shows me animation in only first imageview.I debug Code, it will Go in method but it won't show Any animation in remaining.Below is my Code
-(void)imageNewsAnimation
{
[UIView animateWithDuration:0.35f animations:^{
_imgNews.animationImages=arrnews;
_imgNews.animationDuration=1;
_imgNews.animationRepeatCount=1;
_imgNews.image = [_imgNews.animationImages lastObject];
[_imgNews startAnimating];
} completion:^(BOOL finished) {
[_imgNews stopAnimating];
[self imageEventAnimation];
} ];
}
-(void)imageEventAnimation
{
[UIView animateWithDuration:0.35f delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{
_imgEvents.animationImages=arrEvents;
_imgEvents.animationDuration=1;
_imgEvents.animationRepeatCount=1;
_imgEvents.image = [_imgEvents.animationImages lastObject];
[_imgEvents startAnimating];
} completion:^(BOOL finished) {
[self imageDirectoryAnimation];
} ];
}
-(void)imageDirectoryAnimation
{
[UIView animateWithDuration:0.35f animations:^{
_imgDirectory.animationImages=arrdir;
_imgDirectory.animationDuration=1;
_imgDirectory.animationRepeatCount=1;
_imgDirectory.image = [_imgDirectory.animationImages lastObject];
[_imgDirectory startAnimating];
} completion:^(BOOL finished) {
[self imageInfoAnimation];
} ];
}
-(void)imageInfoAnimation
{
[UIView animateWithDuration:0.35f animations:^{
_imgInfo.animationImages=arrinfo;
_imgInfo.animationDuration=1;
_imgInfo.animationRepeatCount=1;
_imgInfo.image = [_imgInfo.animationImages lastObject];
[_imgInfo startAnimating];
} completion:^(BOOL finished) {
[self imageDirectoryAnimation];
} ];
}
Since startAnimating doesn't have a completion handler, I would set up something like this:
CycleImageView.h
#import <UIKit/UIKit.h>
typedef void (^CycleCompletion)(BOOL finished);
#interface CycleImageView : UIImageView
- (void)startAnimatingWithImages:(NSArray<UIImage *>*)images completion:(CycleCompletion)completion;
#end
CycleImageView.m
#import "CycleImageView.h"
#interface CycleImageView()
#property (nonatomic, copy) CycleCompletion completion;
#end
#implementation CycleImageView
- (void)startAnimatingWithImages:(NSArray<UIImage *>*)images completion:(CycleCompletion)completion {
self.completion = completion;
NSMutableArray *imageRefs = [NSMutableArray array];
for (NSInteger i = 0; i < images.count; i++) {
[imageRefs addObject:(id)images[i].CGImage];
}
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"contents"];
animation.delegate = self;
animation.calculationMode = kCAAnimationDiscrete;
animation.duration = 1;
animation.values = imageRefs;
animation.repeatCount = 1;
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[self.layer addAnimation:animation forKey:#"animation"];
}
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if (self.completion != nil) {
self.completion(flag);
self.completion = nil;
}
}
#end
To use it:
Make imgNews, imgEvents, imgDirectory, and imgInfo all subclasses of CycleImageView. Then, using your supplied methods and variables, the implementation would change to this:
- (void)imageNewsAnimation {
[_imgNews startAnimatingWithImages:arrnews completion:^(BOOL finished) {
if (finished) {
[self imageEventAnimation];
}
}];
}
- (void)imageEventAnimation {
[_imgEvent startAnimatingWithImages:arrEvents completion:^(BOOL finished) {
if (finished) {
[self imageDirectoryAnimation];
}
}];
}
- (void)imageDirectoryAnimation {
[_imgDirectory startAnimatingWithImages:arrdir completion:^(BOOL finished) {
if (finished) {
[self imageInfoAnimation];
}
}];
}
- (void)imageInfoAnimation {
[_imgInfo startAnimatingWithImages:arrinfo completion:^(BOOL finished) {
if (finished) {
// NOTE: Are you intentionally creating this indefinite animation loop?
[self imageDirectoryAnimation];
}
}];
}
Edit:
Created a gist for CycleImageView, as well.
Perform animation with timer like
In viewDidLoad:
timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:#selector(imageAnimation:) userInfo:nil repeats:YES];
i = 0;
then
- (void)imageAnimation:(UIImage *) image {
i++;
if (i > 2) {
i = 0;
}
NSArray *arr = #[[UIImage imageNamed:#"img1"],[UIImage imageNamed:#"img2"],[UIImage imageNamed:#"img3"]];
UIImage * toImage = [arr objectAtIndex:i];
[UIView transitionWithView:self.view
duration:2
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.imageview.image = toImage;
} completion:NULL];
}
Hope this help!
I have couple of images i want to switch. There is a simple function i made for do this:
-(void)imageSlide{
if (!isMoved){
CGRect frame = self.imageSlideshow.frame;
frame.origin.x = self.imageSlideshow.frame.origin.x - 320;
self.imageSlideshow.frame = frame;
NSLog(#"1 caze work");
isMoved = YES;
}
if (isMoved){
CGRect frame = self.imageSlideshow.frame;
frame.origin.x = self.imageSlideshow.frame.origin.x + 320;
self.imageSlideshow.frame = frame;
NSLog(#"2 caze work");
isMoved = NO;
}
}
There is NSTimer which call that function:
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(imageSlide)
userInfo:nil
repeats:YES];
BOOL isMoved; placed in implementation of class.
What i want is, to remove an image and then, shown again (and repeat it every 2 seconds). It would be nice to have smooth animation as well.
That code:
for (int i=0; i<99; i++){
self.imageSlideshow.image = [UIImage imageNamed:(i % 2) ? #"ipd1.jpg" : #"ipd2.jpg"];
CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[self.imageSlideshow.layer addAnimation:transition forKey:nil];
}
Also not working, no idea why. Image stand still. I did import quartz library and include headers.
you can acheive this by using this code :-
#import <QuartzCore/QuartzCore.h>
...
imageView.image = [UIImage imageNamed:(i % 2) ? #"3.jpg" : #"4.jpg"];
CATransition *transition = [CATransition animation];
transition.duration = 2.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[imageView.layer addAnimation:transition forKey:nil];
and NSTimer Job should be done here by transition.duration. So, no need of NSTimer anymore here.
Courtesy :- https://stackoverflow.com/a/2834693/1865424
This piece of code works too :-
// create the view that will execute our animation
UIImageView* imageSlideshow = [[UIImageView alloc] initWithFrame:self.view.frame];
// load all the frames of our animation
imageSlideshow.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#“ipd1.jpg"],
[UIImage imageNamed:#“ipd2.jpg"], nil];
// all frames will execute in 1.75 seconds
imageSlideshow.animationDuration = 1.75;
// repeat the animation forever
imageSlideshow.animationRepeatCount = 0;
// start animating
[imageSlideshow startAnimating];
// add the animation view to the main window
[self.view addSubview:imageSlideshow];
I think you need:
[UIView animateWithDuration:1 options:UIViewAnimationOptionCurveEaseIn
animations:^{
//Change frame here.
} completion:^ (BOOL completed) {}
];
Try this code. It is worked for me.
#pragma mark -
#pragma mark viewDidAppear
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
updateBCK = [NSTimer scheduledTimerWithTimeInterval:(4.0) target:self selector:#selector(changeImage) userInfo:nil repeats:YES];
[updateBCK fire];
}
#pragma mark -
#pragma mark viewDidDisAppear
-(void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
if ([updateBCK isValid]){
[updateBCK invalidate];
updateBCK = nil;
}
}
-(void)changeImage{
static int i=0;
if (i == [myImages count]){
i=0;
}
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:0.6];
backgroundImageView.alpha=1;
backgroundImageView.image =[myImages objectAtIndex:i];
[UIImageView commitAnimations];
i++;
}
It is bug in your code. After setting isMoved = YES, you can't check if isMoved == YES.
I don't know if that is what you mean, but try this code:
-(void)imageSlide{
[UIView animateWithDuration:1 animations:^{
if (!isMoved){
CGRect frame = self.imageSlideshow.frame;
frame.origin.x = self.imageSlideshow.frame.origin.x - 320;
self.imageSlideshow.frame = frame;
NSLog(#"1 caze work");
isMoved = YES;
}
else
{
CGRect frame = self.imageSlideshow.frame;
frame.origin.x = self.imageSlideshow.frame.origin.x + 320;
self.imageSlideshow.frame = frame;
NSLog(#"2 caze work");
isMoved = NO;
}
} completion:^(BOOL finished) {
}];
}
EDIT
Maybe this code will help you:
-(void)slideshow
{
static int i = 0;
UIImage * img = [UIImage imageNamed:(i % 2) ? #"ipd1.jpg" : #"ipd2.jpg"];
[UIView transitionWithView:self.imageSlideshow duration:1.0 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
self.imageSlideshow.image = img;
} completion:^(BOOL finished) {
i++;
[self performSelector:#selector(slideshow) withObject:nil afterDelay:2.0];
}];
}
I have a set of images which i want to display as a slideshow.Is there any transition effects i can apply on UIImageView.
[imgView setImage:[UIImage imageNamed: #"images.jpeg"]];
Yes you can apply transition effects on UIImageView.
First you need to import QuartzCore framework.
#import <QuartzCore/QuartzCore.h>
Then you can use the CoreAnimation as below:
[imgView setImage:[UIImage imageNamed: #"images.jpeg"]];
CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[imgView.layer addAnimation:transition forKey:nil];
Or you can simply animate a group of images in UIImageView as
imgView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image1.jpeg"],
[UIImage imageNamed:#"image2.jpeg"],
[UIImage imageNamed:#"image3.jpeg"],
[UIImage imageNamed:#"image4.jpeg"], nil];
imgView.animationDuration = 1.0f;
imgView.animationRepeatCount = 0;
[imgView startAnimating];
Here is a sample code of how to create a slide show. Make sure you import some images unto your project and in the case method change the wall images to the name of your images.
- (IBAction)start:(id)sender {
_button.hidden = YES;
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:#selector(photoCounter) userInfo:nil repeats:YES];
}
- (void)photoCounter {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.90];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:NO];
[self updatePhoto];
[UIView commitAnimations];
}
- (void)updatePhoto
{
switch (imageCount)
{
case 0:
_images.image = [UIImage imageNamed:#"wall1.jpg"];
break;
case 1:
_images.image = [UIImage imageNamed:#"wall2.jpg"];
break;
case 2:
_images.image = [UIImage imageNamed:#"wall3.jpg"];
break;
case 3:
_images.image = [UIImage imageNamed:#"wall4.jpg"];
break;
case 4:
_images.image = [UIImage imageNamed:#"wall5.jpg"];
break;
default:
break;
}
imageCount ++;
if (imageCount > 4)
imageCount = 0;
}
Try with below code:
NSArray *imageNames = #[#"2_1014.png", #"2_1015.png", #"2_1016.png", #"2_1017.png",#"2_1018.png", #"2_1019.png", #"2_1020.png", #"2_1021.png",#"2_1022.png", #"2_1023.png", #"2_1024.png", #"2_1025.png",#"2_1026.png", #"2_1027.png", #"2_1028.png",
#"2_1029.png",#"2_1030.png",#"2_1030.png",#"2_1029.png",
#"2_1028.png",#"2_1027.png",#"2_1026.png",#"2_1025.png",
#"2_1024.png",#"2_1023.png",#"2_1022.png",#"2_1021.png",
#"2_1020.png",#"2_1019.png",#"2_1018.png",#"2_1017.png",
#"2_1016.png",#"2_1015.png",#"2_1014.png"];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
// Normal Animation
animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, [UIScreen mainScreen].bounds.size.height)];
animationImageView.animationImages = images;
animationImageView.animationRepeatCount=0;
animationImageView.animationDuration = 1;
[self.view addSubview:animationImageView];
[animationImageView startAnimating];
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