Custom UIImage sequence - ios

Can someone help me format some code? I want to show an image on my storyboard and after 5 seconds change it to a new image on screen. Heres what I have so far. This code changes a string after 5 seconds successfully.
double delayInSeconds1 = 5.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds1 * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
hello.text = [NSString stringWithFormat:#"welcome"];
});
double delayInSeconds2 = 5.0;
dispatch_time_t popTime1 = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds2 * NSEC_PER_SEC));
dispatch_after(popTime1, dispatch_get_main_queue(), ^(void){
hello.text = [NSString stringWithFormat:#"hello there"];
});
How can I set up my .h file so that hello.text is something like image=[UIImage imageNamed:#"image1"] Should I use a UIImageView outlet or an UIImage? So far, nothing appears or changes. How do i easily initiate a custom image sequence? The funny thing is I've gotten this to work before but forgot what I did. always save your projects even the dumb ones

You could use the animationImages property of an UIImageView:
UIImageView *image = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 141, 219)];
image.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image1.png"],
[UIImage imageNamed:#"image2.png"],
nil];
image.animationDuration = 5;
image.animationRepeatCount = 0; // infinitely
[image startAnimating];
Example from a blank XCode project :
In ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UIImageView *image;
And in ViewController.m:
#implementation ViewController
#synthesize image = _image;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_image.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"jeu0_icon1.png"],
[UIImage imageNamed:#"jeu0_icon2.png"],
nil];
_image.animationDuration = 5;
_image.animationRepeatCount = 0; // infinitely
[_image startAnimating];
}
And it works (with my 2 png assets well added to the project and the UIImageView added in the stb, of course...

Related

How to set UIImageView zoom animation when the photo being changed

As title, I am beginner so i don't have idea to solve it.
In my code, it just have zoom animation when i turn on the emulator first time,
I want to have the zoom animation when each photo change,
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"1.jpg"],
[UIImage imageNamed:#"2.jpg"],
[UIImage imageNamed:#"3.jpg"],
[UIImage imageNamed:#"4.jpg"],nil];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,10,300,300)];
imageView.animationImages = animationImages ;
imageView.animationRepeatCount = 0;
imageView.animationDuration= 12.0;
[imageView startAnimating];
[self.view addSubview:imageView];
imageView.frame = CGRectMake(150, 150, 20, 20);
CGPoint center = imageView.center;
[UIView animateWithDuration: 1.0f animations:^{
imageView.frame = CGRectMake(10, 10, 300, 300);
imageView.center = center;
}];
}
Thank you in advance for any assistance that can be provided here.
It's not the cleanest code to use animationImages if you want a zoom animation on each image transition. I would create my own custom UIView class to handle the transitions myself so the animations can be tightly synchronized with each transition. But, for the sake of answering your question with a quick unreliable hack, I will use a timer to run an animation at approximately the same frequency as the image transitions. Timers become less accurate over time due, so eventually the zoom effect no longer lines up with the image transitions.
#interface NameOfYourViewController ()
#property(nonatomic, strong) UIImageView* imageView;
#property(nonatomic, strong) NSTimer* imageTransitionTimer;
#property(nonatomic, assign) CGFloat imageScale;
- (void)animateImage;
#end
#implementation NameOfYourViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"1.jpg"],
[UIImage imageNamed:#"2.jpg"],
[UIImage imageNamed:#"3.jpg"],
[UIImage imageNamed:#"4.jpg"],nil];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(10,10,300,300)];
selfimageView.animationImages = animationImages ;
self.imageView.animationRepeatCount = 0;
self.imageView.animationDuration= 12.0;
[self.imageView startAnimating];
[self.view addSubview:self.imageView];
self.imageScale = 1.0f;
self.imageTransitionTimer = [NSTimer scheduledTimerWithTimeInterval:imageView.animationDuration target:self selector:#selector(animateImage) userInfo:nil repeats:YES];
[self.imageTransitionTimer fire];
}
- (void)animateImage
{
[UIView
animateWithDuration:1.0
delay:0.0
options:0
animations:^void () {
self.imageView.transform = CGAffineTransformMakeScale(
self.imageScale,
self.imageScale
);
}
completion:^void(BOOL finished) {
self.imageScale += 0.3f;
}
}];
}
#end

UImage view animation it doesn't work on my iPhone

After build code, it doesn't have any animation on my cellphone
but the code looks good, i don't know how to figure it out ,
and my image is 829 * 445, does it cause this problem ?
Could someone help me to solve this problem i will really appreciate it, thanks
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSArray *animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"1.jpg"],
[UIImage imageNamed:#"2.jpg"],
[UIImage imageNamed:#"3.jpg"],
[UIImage imageNamed:#"4.jpg"],nil];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,150,150)];
imageView.animationImages = animationImages ;
imageView.animationRepeatCount = 2;
imageView.animationDuration= 4.0;
[imageView startAnimating];
[NSTimer scheduledTimerWithTimeInterval:4.0 target:self
selector:#selector(animationDone:)
userInfo:nil repeats:NO];
}
-(void)animationDone:(NSTimer*)inTimer
{
[inTimer invalidate];
inTimer = nil;
NSLog(#"animationDone ");
}
#end
You don't added imageView to your ViewController view.
Try [self.view addSubview:imageView]; in -viewDidLoad
Please use animation block code instead of the older method. The animation will tell you when its done. You don't need to set a timer.
NSArray *animationImages = [NSArray arrayWithObjects:[UIImage imageNamed:#"1.jpg"],
[UIImage imageNamed:#"2.jpg"],
[UIImage imageNamed:#"3.jpg"],
[UIImage imageNamed:#"4.jpg"],nil];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,150,150)];
[UIView animateWithDuration:1.0f animations:^{
for (int loop = 0; loop < 4; loop++) {
UIImage *image = [UIImage imageNamed:[NSString stringWithFornmat:#"%d.jpg", (loop + 1)]];
[imageView setImage:image];
}
} completion:^(BOOL finished) {
NSLog(#"animationDone");
}];
It looks like you're not adding the animating UIImageView to your view hierarchy. Right before your [imageView startAnimating]; line add the below line of code:
[self.view addSubview:imageView];

UIImageView Transition Betwen Multiple Images

I am using the below code to change the UIImageView's image after a short duration. The images being used are stored in an array as you can see.
The problem is, no matter what 'duration' or 'delay' I set, the imageview changes almost instantly to the last image in the array.
Should I instead be using the main thread to add a delay between each image transition?
////////////////////////////////////////////////////////////////
animationCount = 0;
imageArray =[NSMutableArray new];
[imageArray addObject:[UIImage imageNamed:#"gauge1final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge2final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge3final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge4final.png"]];
[imageArray addObject:[UIImage imageNamed:#"gauge5final.png"]];
[self multiStageAnimate];
////////////////////////////////////////////////////////////////
-(void) multiStageAnimate{
[UIView animateWithDuration:5.0
delay:5.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^
{
self.gauge.image = [imageArray objectAtIndex:animationCount];
}
completion:^(BOOL finished){
animationCount ++;
if(animationCount < imageArray.count){
[self multiStageAnimate];
}
else
{
animationCount = 0;
}
}];
}
UIImageView does have a mechanism to accomplish your need.
UIImageView *imageView = [[UIImageView alloc] init];
imageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"image1"],
[UIImage imageNamed:#"image2"],
[UIImage imageNamed:#"image3"], nil];
imageView.animationRepeatCount = 0; // 0 means repeat without stop.
imageView.animationDuration = 1.5; // Animation duration
[imageView startAnimating];
If you are using multiple screens with the same animation, it's better to create one .plist file and then use this anywhere in your project. The steps are as follows:
First, generate one .plist file File-> New File-> Resource ->Property List
Write your code like this:
ViewController.h
#property (weak, nonatomic) IBOutlet UIImageView *dataImageView;
ViewController.m
NSDictionary *picturesDictionary = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"PhotesArray" ofType:#"plist"]];
NSArray *imageNames = [picturesDictionary objectForKey:#"Photos"];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i=0; i<[imageNames count]; i++) {
[images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
//Normal animation
self.dataImageView.animationImages = images;
self.dataImageView.animationDuration = 5.0;
[self.dataImageView startAnimating];
The image property of a UIImageView won't animate. What you need to do is have 2 UIImageView widgets one on top of another. Then, you can animate their alpha properties from 0 to 1 (and vice-versa) with each transition.

When I first load a Detail view from Master View it takes twice as long as each time after that

I have a UITableViewController with 60 cells. The detail view for the cells have 5 imageViews and 5 labels. When I press on a cell for the first time, it takes 2-3 seconds to load the detail view. When I go back to the MasterView and press on a cell, the same one or a different one, it is instantaneous. What could cause this massive lag and how could I fix it?
#implementation DetailViewController{
NSArray *nameArray;
NSArray *flag;
NSArray *pop;
NSArray *yearOfUnion;
NSArray *area;
NSArray *city;
NSArray *abbreviations;
NSArray *resNamea;
NSArray *mainViewa;
NSArray *plateViewa;
}
#synthesize passDataTest;
#synthesize scrollView;
#synthesize stateint;
#synthesize cgvalue;
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"%f", cgvalue);
[scrollView setScrollEnabled:YES];
if ([[UIScreen mainScreen] bounds].size.height == 480) {
[scrollView setContentSize:CGSizeMake(320, 920)];
} else {
[scrollView setContentSize:CGSizeMake(320, 834)];
}
[scrollView addSubview:_contentView];
[_testLabelTaco setText:passDataTest];
NSString *path = [[NSBundle mainBundle] pathForResource:#"statesdata" ofType:#"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
flag = [dict objectForKey:#"StateFlag"];
pop = [dict objectForKey:#"Population"];
yearOfUnion = [dict objectForKey:#"Year"];
area = [dict objectForKey:#"Area"];
city = [dict objectForKey:#"LargeCity"];
abbreviations = [dict objectForKey:#"Abbreviations"];
resNamea = [dict objectForKey:#"ResNames"];
mainViewa = [dict objectForKey:#"MainViewPictures"];
plateViewa = [dict objectForKey:#"LicensePlates"];
_flagView.image = [UIImage imageNamed:[flag objectAtIndex:stateint]];
_populationLabel.text = [pop objectAtIndex:stateint];
_unionYearLabel.text = [yearOfUnion objectAtIndex:stateint];
_areaLabel.text = [area objectAtIndex:stateint];
_cityLabel.text = [city objectAtIndex:stateint];
_abbrLabel.text = [abbreviations objectAtIndex:stateint];
_resNameLabel.text = [resNamea objectAtIndex:stateint];
_mainView.image = [UIImage imageNamed:[mainViewa objectAtIndex:stateint]];
_plateView.image = [UIImage imageNamed:[plateViewa objectAtIndex:stateint]];
// Do any additional setup after loading the view.
}
I am putting in a lot of assumption because what is relevant to your issue here is how the masterView Controller calls the detail view controller and that is not in the code you displayed.
Based on what you showed I am assuming that you are creating a new instance of your detailViewController every time you change the selection - if you are - this is what is causing your overhead.
What you need to do to make your app responsive is to separate the individual setup requirement from - (void) viewDidLoad into another method - And in your MasterViewController call that method and bypass reinitialising the DetailVC instance again. Note this will involve meticulous cleanup and setup but your code avoid a lot of overhead that you would otherwise incur if you keep on recreating [alloc] init] the detail view controller instance all the time - (note - this will also keep the memory requirement down)
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%f", cgvalue);
[scrollView setScrollEnabled:YES];
if ([[UIScreen mainScreen] bounds].size.height == 480) {
[scrollView setContentSize:CGSizeMake(320, 920)];
} else {
[scrollView setContentSize:CGSizeMake(320, 834)];
}
[scrollView addSubview:_contentView];
[self setupDetailVC:self];
}
-(void) setupDetailVC:(ID) sender {
[_testLabelTaco setText:passDataTest];
// Do any additional cleanup and setup after loading the view. }
In your masterViewController: Do this
#synthesize *detailVC; - should have been created in appDelegate code;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[self configureDetailItemForRow:indexPath.row];
}
- (void)configureDetailItemForRow:(NSUInteger)row {
detailVC.property1 = Currentproperty;
detailVC.Utility_sw = NO;
// detailVC.managedObjectContext = managedObjectContext;
[detailVC setupDetailVC:self];
}
One thing you could try is to set the images on a separate thread, using Grand Central Dispatch. This would take the workload off the main thread and your UI shouldn't slow down. You could do something like this:
__weak typeof(self)weakSelf = self; // to avoid a retain cycle
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
__strong typeof(weakSelf)strongSelf = weakSelf;
UIImage * flagImage = [UIImage imageNamed:[strongSelf->flag objectAtIndex:stateint]];
UIImage * mainImage = [UIImage imageNamed:[strongSelf->mainViewa objectAtIndex:stateint]];
UIImage * plateImage = [UIImage imageNamed:[strongSelf->plateViewa objectAtIndex:stateint]];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates on main thread
strongSelf->_flagView.image = flagImage;
strongSelf->_mainView.image = mainImage;
strongSelf->_plateView.image = plateImage;
});
});

Loading images for animation in UIImageView - iOS

I have around 300 images to be loaded for animation the images are named loading001.png, loading002.png, loading003.png, loading004.png………loading300.png
I am doing it in the following way.
.h file
#import <UIKit/UIKit.h>
#interface CenterViewController : UIViewController {
UIImageView *imgView;
}
#end
.m file
#implementation CenterViewController
- (void)viewDidLoad {
[super viewDidLoad];
imgView = [[UIImageView alloc] init];
imgView.animationImages = [[NSArray alloc] initWithObjects:
[UIImage imageNamed:#"loading001.png"],
[UIImage imageNamed:#"loading002.png"],
[UIImage imageNamed:#"loading003.png"],
[UIImage imageNamed:#"loading004.png"],
nil];
}
- (IBAction)startAnimation:(id)sender{
[imgView startAnimating];
}
#end
Is there a efficient way to load the images into a array.
I had tried it with for loop but was not able to figure it out.
You may try out the following code to load images into an array in a better way
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *imgListArray = [NSMutableArray array];
for (int i=1; i <= 300; i++) {
NSString *strImgeName = [NSString stringWithFormat:#"loading%03d.png", i];
UIImage *image = [UIImage imageNamed:strImgeName];
if (!image) {
NSLog(#"Could not load image named: %#", strImgeName);
}
else {
[imgListArray addObject:image];
}
}
imgView = [[UIImageView alloc] init];
[imgView setAnimationImages:imgListArray];
}
There is an easier way to do this. You can simply use:
[UIImage animatedImageNamed:#"loading" duration:1.0f]
Where 1.0f is the duration to animate all the images. For this to work though, your images must be named like this:
loading1.png
loading2.png
.
.
loading99.png
.
.
loading300.png
That is, without padding with 0.
The function animatedImageNamed is available from iOS 5.0 onwards.
Depending on the size of your images, a 300 image animation sequence may be quite the memory hog. Using a a movie might be a better solution.
Your code will crash when run on the device, it is just not possible to decompress that many images into memory on iOS. You will get memory warnings and then your app will be killed by the OS. See my answer to how-to-do-animations-using-images-efficiently-in-ios for a solution that will not crash on the device.

Resources