Changing UIImageView dynamically - objective-c

-(void)viewDidLoad {
NSMutableArray *coolImagesArray = [[NSMutableArray alloc] initWithObjects:#"active-1.jpg", #"active-2.jpg", #"active-3.jpg", #"active-4.jpg", #"active-5.jpg", nil];
}
-(void)someMethodWithData {
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *imagesArray = [[NSMutableArray alloc] init];
NSMutableString *inactiveString = [[NSMutableString alloc] init];
for (int i = 0; i < progress; i++) {
imageView.image = [UIImage imageNamed:[coolImagesArray objectAtIndex:i]];
inactiveString = [NSMutableString stringWithFormat:#"inactive-%d.png",i];
[imagesArray addObject:imageView];
}
UIImage *setImage = [UIImage imageNamed:#"inactive-1.png"];
for (int i = 0; i < [imagesArray count]; i++) {
[(UIImageView*)[imagesArray objectAtIndex:i] setImage:setImage];
}
});
}
This will always set the last or i(th) image correctly. It will not loop and change all the images I need. Is there another way to manage this?

imageView is pointing to one UIImageView object and in a loop you are changing the image of imageView not adding new UIImageView object to your array. All the objects inside the array pointing to 1 UIImageView object. So it is so normal that you can only change the last object's image only, because there is no other object in your array.
you should do it like:
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *imagesArray = [[NSMutableArray alloc] init];
NSMutableString *inactiveString = [[NSMutableString alloc] init];
for (int i = 0; i < progress; i++) {
UIImageView *temp = [[UIImageView alloc] initWithFrame:imageView.frame];
temp.image = [UIImage imageNamed:[coolImagesArray objectAtIndex:i]];
inactiveString = [NSMutableString stringWithFormat:#"inactive-%d.png",i];
[imagesArray addObject:temp];
}
UIImage *setImage = [UIImage imageNamed:#"inactive-1.png"];
for (int i = 0; i < [imagesArray count]; i++) {
[(UIImageView*)[imagesArray objectAtIndex:i] setImage:setImage];
}
});

For starters, I would create the image once so as to save memory.
I would also cast the object to a UIImageView (Not sure how that isn't getting flagged in xcode).
Lastly I would wrap it in a dispatch_async() to make sure it's happening on the main UI thread, because it could be getting called on a background thread and somehow the last image makes it to the main run loop, either way this is what it would look like:
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *setimage = [UIImage imageNamed:#"set-image.png"];
for (int i = 0; i < [imagesArray count]; i++) {
[(UIImageView *)[imagesArray objectAtIndex:i] setImage:setimage]];
}
});

Related

UITableView checking for detail view

I don't speak english very well so I hope that you understand.
I have to control my source data(an array of array from a csv) to see if it have the same element double, if this is true I want to insert only one of this in my List of TableView, but I have to store this, cause I need to know which of this element in the list must visualize a detail view. If the element is double in the source data I have to show the detail view, else nothing.
I tried a bit of method but I haven't found the solution, yet.
This is my code:
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *listaNonOrdinata = [[NSMutableArray alloc]init];
self.navigationItem.title = #"Tipologia";
NSString *fileString = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Lista1" ofType:#"csv"] encoding:NSUTF8StringEncoding error:nil];
record = [fileString csvRows];
dettaglio = [[NSMutableArray alloc]init];
id doppio = nil;
for (int i=1; i < record.count; i++) {
for (int j=0; j < listaNonOrdinata.count; j++) {
doppio = [[record objectAtIndex:i] firstObjectCommonWithArray:listaNonOrdinata];
if (doppio == nil) {
[dettaglio addObject:[NSNumber numberWithBool:NO]];
} else {
[dettaglio addObject:[NSNumber numberWithBool:YES]];
}
}
if (doppio == nil) {
[listaNonOrdinata addObject:[[record objectAtIndex:i]objectAtIndex:0]];
}
}
//Ordino array in ordine alfabetico
lista = [[NSArray alloc]init];
lista = [listaNonOrdinata sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
[listaNonOrdinata release];
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
Can everyone help me?
Thanks.
I'VE FOUND THE SOLUTION:
I had badly configured the array, now it works fine!

How to Add UIImage to NSMutableArray

I'm trying to add my UIImage from web service to my NSMutableArray using this code:
for (int i=0; i<[totalRowCountString intValue]; i++)
{
NSString *criticsRatingString = [[JSON valueForKeyPath:#"movies.ratings.critics_rating"] componentsJoinedByString:#" "];
NSLog(#"criticsRatingString: %#", criticsRatingString);
if ([criticsRatingString isEqualToString:#"Certified Fresh"])
{
self.ratingImage = [UIImage imageNamed:#"rt_certified_fresh.png"];
}
else if ([criticsRatingString isEqualToString:#"Fresh"])
{
self.ratingImage = [UIImage imageNamed:#"rt_fresh.png"];
}
else if ([criticsRatingString isEqualToString:#"Rotten"])
{
self.ratingImage = [UIImage imageNamed:#"rt_rotten.png"];
}
else if ([criticsRatingString isEqualToString:#"Spilled"])
{
self.ratingImage = [UIImage imageNamed:#"rt_spilled.png"];
}
else if ([criticsRatingString isEqualToString:#"Upright"])
{
self.ratingImage = [UIImage imageNamed:#"rt_upright.png"];
}
[tomatorRatingImages addObject:self.ratingImage];
NSLog(#"tomatoRatingImages: %#", tomatorRatingImages);
}
But my NSLog for tomatoRatingImages returns NULL. Any ideas why it returns NULL?
UPDATE: my NSMutableArray is already initialized in my viewWillAppear method.
You must initialize the array before adding objects to it.
NSMutableArray *tomatorRatingImages = [[NSMutableArray alloc] init];
NSMutableArray * tomatorRatingImages =[[NSMutableArray alloc]init];
[tomatorRatingImages addObject:[UIImage imageNamed:#"rt_spilled.png"]];
[tomatorRatingImages addObject:[UIImage imageNamed:#"rt_spilled1.png"]];
[tomatorRatingImages addObject:[UIImage imageNamed:#"rt_spilled2.png"]];
you can enter multiple image in NSMutableArray.
If you have a property for the NSMutableArray instance, it's better to write getter to initialize it. It takes care of initializing the variable only ones also it gets loaded only when it's required.
-(NSMutableArray *) tomatorRatingImages {
if(_tomatorRatingImages == nil) {
_tomatorRatingImages = [NSMutableArray alloc] init];
}
return _tomatorRatingImages;
}
Initialize like this
NSMutableArray * tomatorRatingImages =[[NSMutableArray alloc]initWithCapacity:3];

Immediately initialize UIImage

I have an array of UIImage objects as follows:
frames = [[NSMutableArray alloc] initWithCapacity:[sortedArray count]];
for (int nDx = 0; nDx < [sortedArray count]; nDx++)
{
NSString * sImageName = [sortedArray objectAtIndex:nDx];
[frames addObject:[UIImage imageWithContentsOfFile:[NSString stringWithFormat:#"%#/%#", imageFolderPath, sImageName]]];
}
In my timer method I am doing the following to cycle through the images:
self.image = [frames objectAtIndex:currentFrame];
currentFrame++;
if (currentFrame >= [frames count]) currentFrame = 0;
However, when I start the timer the images cycle slow the first time, and then everything works as expected. I have also tried this without a timer.
How can I pre-load the images so they are ready to go when my timer starts?
Thanks for the help.
You can have a separate thread to load the images, using this code.
If it works I'll add it here.
Here img_array is UIImageView
img_array.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"img_1.png"],
[UIImage imageNamed:#"img_2.png"],
[UIImage imageNamed:#"img_3.png"],nil];
[img_array.animationImages setAnimationRepeatCount:HUGE_VAL];
img_array.animationImages .animationDuration = 4;
[img_array.animationImages startAnimating];
[self.view addSubview:img_array]
Try this:

CAAnimation not animating my sequence of images

I'm having trouble with animating with CAAnimation, it doesn't seem to give me any errors but it isn't animating. I'm confused
NSMutableArray *animationImages = [NSMutableArray array];
//Adding images into array
for (int i=0;i<=5;i++){
UIImage *imgfile = [NSString stringWithFormat:#"%#/ConusOverlay/%d_ConusOverlay.gif",documentsPath,i];
[animationImages addObject: imgfile];
}
CAKeyframeAnimation *animationSequence = [CAKeyframeAnimation animationWithKeyPath: #"contents"];
animationSequence.calculationMode = kCAAnimationLinear;
animationSequence.autoreverses = NO;
animationSequence.duration = 1;
animationSequence.repeatCount = HUGE_VALF;
NSMutableArray *animationSequenceArray = [NSMutableArray array];
for (UIImage *image in animationImages) {
[animationSequenceArray addObject:image]; //<--Does this have to be (id)image.CGImage ?, if I am correct you are unable to add CGImage to an array
}
animationSequence.values = animationSequenceArray;
[mlLayer.contents addAnimation:animationSequence forKey:#"contents"];
CoreAnimation usually takes CGImageRefs and not UIImages. Try replacing the image with the (id)image.CGImage as you suggested. Arrays can store CGImageRefs!

Create an array of UIImages from camera roll

I would like to get all of the images from the camera roll and create an array of UIImages from them.
I have been trying to figure out how to do this for about a day now and I've gotten nowhere. I can't seem to figure out how to retrieve only items from the Camera Roll. It appears that all of the samples that I've seen all enumerate over all of the photo albums. I might be wrong about that though.
Any help would be appreciated. Thanks!
Have you tried ALAssetsLibrary? like this:
assets = [[NSMutableArray array] init]; // Prepare array to have retrieved images by Assets Library.
void (^assetEnumerator)(ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *asset, NSUInteger index, BOOL *stop) {
if(asset != NULL) {
[assets addObject:asset];
dispatch_async(dispatch_get_main_queue(), ^{
[self insertArray];
});
}
};
void (^assetGroupEnumerator)(ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
}
};
// Create instance of the Assets Library.
library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos // Retrieve the images saved in the Camera roll.
usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error) {
NSLog(#"Failed.");
}];
that'll nab them. then do this to render them (this is wicked hacky. you'll want to import them as needed and not all at once like this, or you'll run into memory issues and crash)
-(void) insertArray {
int i = assetCount++;
if (i>20) {
return;
}
ALAssetRepresentation *rep = [[assets objectAtIndex:i] defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
CGSize cSize = CGSizeMake(75,75);
UIImage *largeimage = [UIImage imageWithCGImage:iref];
UIImage *resizedimage = (UIImage *)[largeimage resizedImage:cSize interpolationQuality:kCGInterpolationHigh];
UIImageView *newView = [[UIImageView alloc] initWithImage:resizedimage];
if((i>0)&&(i%4 == 0)){
rowCount++;
}
colCount = i%4;
newView.frame = CGRectMake(4+(colCount*(75+4)), 4+(rowCount*(75+4)), 75, 75);
[sv addSubview:newView];
[sv setContentSize:CGSizeMake(320, 85+(rowCount*(75+4)))];
NSLog(#"sv frame size is %# and i is %i", NSStringFromCGRect(sv.frame), i);
}