I'm using a custom created loading spinner for my iOS app, but the edges looks rough on a coloured background as expected from a GIF.
How do other apps handle this situation? Do they use anything other than GIF, maybe APNG or something? Cause with GIF, the edges are always going to be rough, if matte is used, it would look good on just one color and not the others.
Any solution?
The UIImageView class provides the easiest way for developers to implement animations. All you need to do is to create an UIImageView object with a series of images for animating.
Example
// Load images
NSArray *imageNames = #[#"win_1.png", #"win_2.png", #"win_3.png"];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++) {
[images addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
// Normal Animation
UIImageView *animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 193)];
animationImageView.animationImages = images;
animationImageView.animationDuration = 0.5;
[self.view addSubview:animationImageView];
[animationImageView startAnimating];
Related
I am using the following code to show the splash screen :
UIImageView *defaultImage = [[UIImageView alloc] init];
defaultImage.frame = defaultImageFrame;
// for iOS 9 Compatability
//NSMutableArray *buttonsArray = [[NSMutableArray alloc] initWithCapacity:1];
NSMutableArray *buttonsArray = [NSMutableArray arrayWithCapacity:1];
for (int i = 1; i<=3; i++)
{
[buttonsArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"img00%d", i] ofType:#"png"]]];
}
mAnimatedButtons = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, WIDTH_DEVICE, HEIGHT_DEVICE)];
[mAnimatedButtons setUserInteractionEnabled:NO];
[mAnimatedButtons setAnimationImages:buttonsArray];
[mAnimatedButtons setAnimationRepeatCount:0];
[mAnimatedButtons setAnimationDuration:2.0];
[mAnimatedButtons startAnimating];
[defaultImage addSubview:mAnimatedButtons];
[self.view addSubview:defaultImage];
And i will remove the splash screen after this
[mAnimatedButtons stopAnimating]; //here animation stops
[mAnimatedButtons removeFromSuperview]; // here view removes from view hierarchy
mAnimatedButtons = nil;
self.defaultImage=nil;
[self.defaultImage removeFromSuperview];
[self.view.layer removeAllAnimations];
for (CALayer* layer in [self.view.layer sublayers])
{
[layer removeAllAnimations];
}
Adding this code increases the memory usage upto 300 Mb.
Removing this it has only 100 Mb.
I tried the following code also
self.defaultImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, WIDTH_DEVICE, HEIGHT_DEVICE)];
self.defaultImage.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"img001.png"],
[UIImage imageNamed:#"img002.png"],
[UIImage imageNamed:#"img003.png"],
nil];
//self.defaultImage.animationDuration = 1.0f;
self.defaultImage.animationRepeatCount = 0;
[self.defaultImage setAnimationDuration:2.0];
[ self.defaultImage startAnimating];
[self.view addSubview: self.defaultImage];
Even though the result is same.
Images, when used in the app, may require considerably more memory than the size of the asset in persistent storage might otherwise suggest. Assets are frequently compressed (e.g. JPG or PNG), but when you use the image, they're uncompressed, often requiring 4 bytes per pixel (one byte for red, green, blue, and alpha, respectively). So, for example, a iPhone 7+ full-screen retina image can require 14mb when you use the image. So, the memory-efficient technique is to employ lazy loading, not creating the UIImage objects until you absolutely need them. And, as Jerry suggested, because the amount of memory is determined by the size of the image and not the imageview in which you use the image, if your images have dimensions greater than required by the UIImageView in which you use them (i.e. width and height of the imageview times the "scale" of the device), you may want to resize the image accordingly.
when the user touch the button the below code show the image.i want show different images like "bear,cat,cow,dog" continuously without user touch the button.can any one help me.
NSMutableArray *dashBoy = [NSMutableArray array];
for (i = 1; i<= 12; i++)
{
butterfly = [NSString stringWithFormat:#"bear_%d.png", i];
if ((image = [UIImage imageNamed:butterfly]))
[dashBoy addObject:image];
}
[stgImageView setAnimationImages:dashBoy];
[stgImageView setAnimationDuration:4.0f];
[stgImageView setAnimationRepeatCount:2];
[stgImageView startAnimating];
You could do as below:-
Firstly, create a UIImageView property like below,
#property (nonatomic,weak) IBOutlet UIImageView *imageView; //Also connect it with storyboard or xib.
Then you could write down IBAction as follow:-
- (IBAction)startTap:(id)sender {
[self.imageView setAnimationDuration:1.0f]; //You could change the duration for making animation fast or slow.
[self.imageView setAnimationImages:imageArray]; //imageArray is NSArray of images of which you want to show slide show.
[self.imageView startAnimating]; //simply to start animation.
}
- (IBAction)stopTap:(id)sender {
[self.imageView stopAnimating]; //To stop animation.
}
try this..
create two instance objects like
NSMutableArray * imagesArray; and UIImageView *animationImageView;
-(void)viewDidLoad
{
NSArray *imageNames = #[#"img1.png", #"img2.png", #"img3.png", #"img4.png",#"img5.png"];
imagesArray = [[NSMutableArray alloc]init];
NSMutableArray *images = [[NSMutableArray alloc] init];
for (int i = 0; i < imageNames.count; i++)
{
[imagesArray addObject:[UIImage imageNamed:[imageNames objectAtIndex:i]]];
}
animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 193)];
animationImageView.animationImages = imagesArray;
animationImageView.animationDuration = 0.5; // set your own
[self.view addSubview:animationImageView];
}
and to start and stop two UIButton Actions
-(IBAction)startAnimation:(UIButton*)sender
{
[animationImageView startAnimating];
}
-(IBAction)stopAnimation:(UIButton*)sender
{
[animationImageView stopAnimating];
}
I'm running into a problem trying to perform a certain effect on iOS with tableviews...I know this can be done with normal UIViewControllers, but can't seem to pull it off with UITableViewControllers.
The effect is showing a clear background image behind a tableview and and as the user scrolls down the tableview, the background blurs. No problem getting that to happen.
The issue I'm having is that using a UITableViewController, I can only seem to have 1 ImageView behind the TableView and to create the blurring effect, the extension i am using will require 2 image views, one of which is the blurred image and has it's opacity set to 0 at launch.
This is code I know works using a UIViewController:
UIImage *background = [UIImage imageNamed:#"bg_004.png"];
self.backgroundImageView = [[UIImageView alloc] initWithImage:background];
self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
[self.view addSubview:self.backgroundImageView];
self.blurredImageView = [[UIImageView alloc] init];
self.blurredImageView.contentMode = UIViewContentModeScaleAspectFill;
self.blurredImageView.alpha = 0;
[self.blurredImageView setImageToBlur:background blurRadius:10 completionBlock:nil];
[self.view addSubview:self.blurredImageView];
This is the code I am trying on the UITableViewController that does not work:
UIImage *background = [UIImage imageNamed:#"bg_004.png"];
self.backgroundImageView = [[UIImageView alloc] initWithImage:background];
self.backgroundImageView.contentMode = UIViewContentModeScaleAspectFill;
[self.tableView setBackgroundView:self.backgroundImageView];
// Also tried this, to no success
[self.tableView.backgroundView addSubview:self.blurredBackgroundView];
self.blurredBackgroundView = [[UIImageView alloc] init];
self.blurredBackgroundView.contentMode = UIViewContentModeScaleAspectFill;
self.blurredBackgroundView.alpha = 0;
[self.blurredBackgroundView setImageToBlur:background blurRadius:10 completionBlock:nil];
[self.tableView setBackgroundView:self.blurredBackgroundView];
// Also tried this, to no success
[self.tableView.backgroundView addSubview:self.blurredBackgroundView];
If anyone has some suggestions how how to make this work, i'd love some advice. I really wouldn't like to change my code from a TableViewController to a UIViewController
Set the table view's backgroundView property to point to an instance of UIView, and then add your image views as subviews of the new view. You can't directly add subviews to instances of UIImageView
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.
I make a app which include a image view within scroll view.
I have 3 classes and each class add images into image view.
When i press button1, it call class1 and it fill Class1images(from image001 to image200).
When i press button2, it call class2 and it fill Class2images(from image201 to image400)
The problem is when i call class1, image view show class1images(from image001 to image200).
After calling class1, i call class2.
When i call class2, my image view can't show class2images(from image201 to image400)
But, class1Images (from image001 to image200) are remaining in app.
I think class1 images are still in memory, so that class2 images can't add to memory.
I want to remove class1images when i call class2.
When i call next class, it will remove old images in memory and replace with new images.
But, my app is develop with storyboard and ARC.
So, i can't release memory manually in ARC mode.
Is there any ways to remove old images in memory?
- (void)viewDidLoad{
[super loadView];
self.view.backgroundColor = [UIColor grayColor];
ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width,self.view.frame.size.height)];
ScrollView.pagingEnabled = YES;
NSInteger numberOfViews = 200;
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * self.view.frame.size.width;
// Create a UIImage to hold Info.png
UIImage *image1 = [UIImage imageNamed:#"Image001.jpg"];
UIImage *image2 = [UIImage imageNamed:#"Image002.jpg"];
:
:
UIImage *image200 = [UIImage imageNamed:#"Image200.jpg"];
NSArray *images = [[NSArray alloc] initWithObjects:image1,image2, . . . ,image200,nil];
ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin, 0,self.view.frame.size.width, self.view.frame.size.height)];
[ImageView setImage:[images objectAtIndex:i]];
[ScrollView addSubview:ImageView];}
ScrollView.contentSize = CGSizeMake(self.view.frame.size.width*numberOfViews,self.view.frame.size.height);
[self.view addSubview:ScrollView];}
setting an imageview's animationImages property to a new array will remove the olf array and animate the new one.
to be 110% safe call stopAnimation, set the images, call startAnimation
I think your scrollview is not getting cleaned up. You need to remove previous images from scrollView and after that add images from next class.
try to implement something like this for removing images from scrollview and after this add other images on button click
for(UIView *subView in self.ScrollView.subviews)
{
if([subView isKindOfClass:[UIImageView class]])
[subView removeFromSuperview];
}
Hopefully can help you. Just give it a try.