i have code to display a single image from json array data in a UIImageView.
i want to display all images in multiple UIImageViews.
plz suggest me how to loop images to display all.
json array data link:
Here's code from my app
NSString *urlString=[NSString stringWithFormat:#"http://ielmo.xtreemhost.com/array.php"];
NSURL * url=[NSURL URLWithString:urlString];
NSData *data =[NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableArray *json=(NSMutableArray*)[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%#",[json objectAtIndex:0]);
NSString *imageString=[NSString stringWithFormat:#"%#",[json objectAtIndex:0]];
NSURL * urlone=[NSURL URLWithString:imageString];
NSData *datanew =[NSData dataWithContentsOfURL:urlone];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
[imageView setImage:[UIImage imageWithData:datanew]];
testView = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 300.0f, 300.0f, 200.0f)];
[testView addSubview:imageView];
[self.view addSubview:testView];
NSMutableArray *arr=[[NSMutableArray alloc] init];
NSString *urlString=[NSString stringWithFormat:#"http://ielmo.xtreemhost.com/array.php"];
NSURL * url=[NSURL URLWithString:urlString];
NSData *data =[NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableArray *json=(NSMutableArray*)[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSLog(#"%d",[json count]);
NSLog(#"%#",[json objectAtIndex:0]);
NSString *imageString;
for (int i=0; i<[json count]; i++) {
imageString=[NSString stringWithFormat:#"%#",[json objectAtIndex:i]];
[arr addObject:imageString];
}
NSLog(#"%#",arr);
// NSString *imageString=[NSString stringWithFormat:#"%#",[json objectAtIndex:0]];
NSURL * urlone=[NSURL URLWithString:imageString];
NSData *datanew =[NSData dataWithContentsOfURL:urlone];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
[imageView setImage:[UIImage imageWithData:datanew]];
UIView * testView = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 300.0f, 300.0f, 200.0f)];
[testView addSubview:imageView];
[self.view addSubview:testView];
After parsing JSON response use follow code
UIScrollView *testView = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,320,480)];
for(int i=0; i<[json count]; i++){
NSLog(#"%#",[json objectAtIndex:i]);
NSString *imageString=[NSString stringWithFormat:#"%#",[json objectAtIndex:i]];
NSURL * urlone=[NSURL URLWithString:imageString];
NSData *datanew =[NSData dataWithContentsOfURL:urlone];*
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,i*480,320,480)];
[imageView setImage:[UIImage imageWithData:datanew]];
[testView addSubview:imageView];
}
[self.view addSubView:testView];
*Note: Now you are going with Synchronous Request to download & load images in the view. It is not a good approach. Use Asynchronous requests for downloading images and loading them.
Find the following URL for asynchronous image downloading
Asynchronous downloading of images for UITableView with GCD
you can get an image dictionary into array like this, into data object
Suppose i have PostClubDC class with posDC obj
for(NSDictionary *returnDicto in dataArray)
{
PostClubDC *postDC = [[PostClubDC alloc] init];
NSDictionary * returnDict = [returnDicto objectForKey:#"club_info"] ;
postDC.postID = [[returnDict objectForKey:#"Id"]integerValue];
postDC.postName = [returnDict objectForKey:#"name"];
postDC.postImage = [returnDict objectForKey:#"image"];
[yourDataArray addObject:postDC];
}
Related
I am retrieving data from a mysql database and want to display it in a textview. So, I created a for loop for each piece of data. The problem is it only creates one textview and therefore only displays the first piece of retrieved data. My code is below:
-(void) getData:(NSData *) data {
NSError *error;
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
}
-(void) start {
//NSLog(#"%lu", (unsigned long)[json count]);
NSURL *url = [NSURL URLWithString:kGETUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
[self getData:data];
NSIndexPath *indexPath;
NSDictionary *info = [json objectAtIndex:indexPath.row];
for (int i = 0; i < [json count]; i++)
{
//NSLog(#"%#", json);
UITextView *myTextView = [[UITextView alloc] init];
myTextView.text = [info objectForKey:#"title"];
[self.view addSubview:myTextView];
[myTextView sizeToFit];
}
}
json is an array and info is one dictionary in json.
You are looping five times over json but printing the same info. You need:
int yPos = 0;
for (int i = 0; i < [json count]; i++)
{
//NSLog(#"%#", json);
info = [json objectAtIndex:i];
UITextView *myTextView = [[UITextView alloc] init];
myTextView.text = [info objectForKey:#"title"];
[self.view addSubview:myTextView];
[myTextView sizeToFit];
yPos += myTextView.frame.size.height;
myTextView.frame = CGRectMake(0, yPos, myTextView.frame.size.width, myTextView.frame.size.height);
}
I have a UIImageView in side a UIView, which displays an object #"photos" in a JSON Array as such: http://topmobiletrends.com/wp-content/uploads/2013/10/screen568x568-14.jpeg
My NSLog tells me that all the objects have been parsed correctly. But the UIImageViews inside UIViews show the same image, I believe it is the first object [0]. I need to have the views show each image for all of the objects for the #"photos" key.
Here is my code for my ViewController.m:
. . .
#interface ViewController ()
{
NSInteger index;
}
//#property (nonatomic, weak)NSURL *imageURL;
#end
#implementation ViewController
#synthesize menuButton;
#synthesize myImage;
#synthesize priceLabel;
-(void)viewDidLoad{
[super viewDidLoad];
NSURL *bburl = [NSURL URLWithString:#"http://www.suchandsuch.com/api/sites"];
NSData *jsonData = [NSData dataWithContentsOfURL:bburl];
NSURLSession *session = [NSURLSession sharedSession];
NSURLRequest *request = [[NSURLRequest alloc]initWithURL:bburl];
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:bburl completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error){
NSLog(#"%#", response);
NSData *data = [[NSData alloc]initWithContentsOfURL:location];
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSString *imageURLString = [[[dataDictionary objectForKey:#"sites"] objectAtIndex:index] objectForKey:#"photo"];
NSURL *imageURL = [NSURL URLWithString:[imageURLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSLog(#"sites : %#", imageURLString);
NSArray *sitesArray = [dataDictionary objectForKey:#"sites"];
NSMutableArray *photos = [[NSMutableArray alloc]initWithArray:sitesArray];
for (NSDictionary *item in sitesArray) {
MyObject *current = [MyObject alloc];
current.name = [item objectForKey:#"name"];
current.url = [item objectForKey:#"url"];
current.price = [item objectForKey:#"price"];
current.photo = [item objectForKey:#"photo"];
[photos addObject:current];
NSLog(#"%#", current.photo);
}
for (MyObject *photo in photos)
{
dispatch_async(dispatch_get_main_queue(),^{
UIView *dView = [[UIView alloc]initWithFrame:CGRectMake(30,30,258,229)];
UIImage *image = [UIImage imageWithData:data];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]];
imageView.frame = CGRectMake(30, 30, 258, 229);
//Get image from url
[self.imageView setImageWithURL:imageURL];
//[self.myImage addSubview:imageView];
[dView addSubview:imageView];
[self.view addSubview:dView];
// priceLabel.text = [[[dataDictionary objectForKey:#"sites"] objectAtIndex:index] objectForKey:#"price"];
});
}
}];
[task resume];
}
There are a few issues with the code.
You are adding both NSURL and name string to the photos array but when reading you are expecting all of them to be photos.
I would recommend create a data structure called Photo which contains
#interface PhotoClass :NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSURL *url;
#property (nonatomic, strong) NSString *price
#property (nonatomic, strong) NSString *photo;
#end
That way you can do the following when parsing your data.
PhotoClass *current = [PhotoClass alloc];
current.name = [item objectForKey:#"name"];
current.url = [item objectForKey:#"url"];
current.price = [item objectForKey:#"price"];
current.photo = [item objectForKey:#"photo"];
// Add to array
[photos addObject:current];
And then when you are ready to display use the url from each PhotoClass object.
The next issue in your code is with the image view setup. First of all You will need to create as many ImageViews. each one needs to be offset to the other can be visible behind that image. Plus the image view seems to be getting set in many diff ways. Is that just a typo? :
for (PhotoClass *photo in photos)
{
dispatch_async(dispatch_get_main_queue(),^{
UIView *dView = [[UIView alloc]initWithFrame:CGRectMake(50,50,258,229)];
// The frame of each of the frames needs to be offset a little ..
// so you need to figure out how to calculate that for each image.
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photo.url]];
[dView addSubview:imageView];
[self.view addSubview:dView];
....
}];
}
At the end of the loop you should have as many image views in view as objects in photos.
Disclaimer - code not compiled and typed directly into stackoverflow browser
I am getting image From JSON url.I tried like this but i did't not get image
NSMutableArray *al=[NSJSONSerialization JSONObjectWithData:webData options:0 error:nil];
NSLog(#"all NSMutable2%#",al);
NSDictionary *dict = [al objectAtIndex:1];
NSString *title=[dict objectForKey:#"dealimage"];
NSLog(#"all DIC%#",title);
NSData *data1 = [[NSData alloc] initWithData:[NSData
dataFromBase64String:title]];
NSLog(#"********************************%#",data1);
NSData* data = [Base64 decode:title ];
UIImage *image = [UIImage imageWithData:data];
dig=[[UIImageView alloc]initWithImage:image];
[self.view addSubview:dig];
dig.frame = CGRectMake(0, 25 , 150,150);
My idea is first NSString data converted to NSData and Then NSData pass to UIImage.But No luck
So Please give me any idea
#import "NSData+Base64.h"
//Creating the data from your base64String
NSData *data = [[NSData alloc] initWithData:[NSData dataFromBase64String: title]];
//Now data is decoded. You can convert them to UIImage
UIImage *image = [UIImage imageWithData:data];
dig=[[UIImageView alloc]initWithImage:image];
dig.frame = CGRectMake(0, 25 , 150,150);
[self.view addSubview:dig];
Currently in my AppDelegate.m I have the code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.window makeKeyAndVisible];
CGRect rect = [[UIScreen mainScreen] bounds];
UIImageView *imageView =[[UIImageView alloc] initWithFrame:rect];
imageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"Comp 2_00000.png"],..., nil];
imageView.animationDuration = 6;
imageView.animationRepeatCount = 1;
[imageView startAnimating];
[self.window addSubview:imageView];
return YES;
}
Which plays an animation I have once my view did load code in my ViewController.m has loaded some data which takes around 5 seconds.
I load the data like this using JSON and URLS:
NSURL *url = [NSURL URLWithString:#"http://xxxxxxxx.co.uk/untitled%20folder/jsonimages.php"];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers error:&error];
Is there anyway for the animation to play while the data is loading?
Create a helper function (make it static if you need to reuse it):
Function:
-(UIImageView *) InitImageView{
[self.window makeKeyAndVisible];
CGRect rect = [[UIScreen mainScreen] bounds];
UIImageView *imageView =[[UIImageView alloc] initWithFrame:rect];
imageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"Comp 2_00000.png"],..., nil];
//imageView.animationDuration = 6;
imageView.animationRepeatCount = 1;
[self.view addSubview:imageView];
return imageView;
}
Ansynchronous Task:
//Start Animation
UIImageView *imageView = [self InitImageView];
[imageView startAnimating];
dispatch_queue_t queue = dispatch_queue_create("co.uk.bits.bots", NULL);
dispatch_async(queue, ^{
NSURL *url = [NSURL URLWithString:#"http://xx.co.uk/jsonimages.php"];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
//Stop Animation
[imageView stopAnimating];
});
});
What you could do is to dispatch the data request and then call the animation:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:#"http://xxxxxxxx.co.uk/untitled%20folder/jsonimages.php"];
NSData *jsonData = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
//Main thread stuff, after loading the data
[self animate];
});
});
....
- (void)animate {
CGRect rect = [[UIScreen mainScreen] bounds];
UIImageView *imageView =[[UIImageView alloc] initWithFrame:rect];
imageView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:#"Comp 2_00000.png"],..., nil];
imageView.animationDuration = 6;
imageView.animationRepeatCount = 1;
[imageView startAnimating];
[self.view addSubview:imageView];
}
This code may get your app rejected from the app store because it will force the user to wait for six seconds on every app launch. the Apple guidelines say that app launches should happen as fast as possible.
Could you refactor it so that your initial view controller can be displayed without the data at first, then update it incrementally as the data becomes available?
If the data is loaded from the network you could also cache it so that subsequent launches are faster.
I'm having a trouble dynamically adding UIButtons with background image as subviews to a UIScrollView. Its kind of a image gallery using UIButtons on a scrollView. I have used this method for couple of my apps, it works fine for me with the static contents.
But this time, Im loading images from a web service and saved to documents directory, then call the method to create the gallery. Logic is same with my other apps. But I cannot figure out what is the issue here.
I'll put here both the codes one is for retrieving data and other is the creating gallery.
Data retrieving from server
-(void)loadDataFromServer{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
arrCats = [[NSMutableArray alloc]init];
arrPromos = [[NSMutableArray alloc]init];
//[spinMenu startAnimating];
// load promo images from the server
for(int i=0;i<[arrPromos count];i++)
{
NSString *urlString = [Constants getImages:[[arrPromos objectAtIndex:i] objectForKey:#"image"]];
NSLog(#"Get Images API Call : %#", urlString);
NSURL *imageurl = [NSURL URLWithString:urlString];
//get a dispatch queue
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageurl];
//this will set the image when loading is finished
dispatch_async(dispatch_get_main_queue(), ^{
if(imageData != nil){
// save the images temporally
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:[[arrPromos objectAtIndex:i] objectForKey:#"image"]]; //Add the file name
[imageData writeToFile:filePath atomically:YES];
}
});
});
}
// Load promotions from server
dispatch_async(queue, ^{
NSLog(#"Promotions Loading Started");
NSString *urlString = [Constants getAllPromotions:#"GetPromo.php"];
NSLog(#"Get Promotions API Call : %#", urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// Specify that it will be a GET request
request.HTTPMethod = #"GET";
[request setHTTPShouldHandleCookies:NO];
NSURLResponse *responseURL;
NSError *error;
NSData *dataPromotions = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseURL error:&error];
if (responseURL == nil)
{
// Check for problems
if (error != nil)
{
NSLog(#"Get Promtions Connection failed! Error - %#", [error localizedDescription]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Error!" message:#"Promotions data failed to load!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
else
{
NSString *responseString = nil;
responseString = [[NSString alloc] initWithData:dataPromotions encoding:NSUTF8StringEncoding];
if ([responseString rangeOfString:#"error"].location == NSNotFound)
{
NSDictionary *response = [[NSDictionary alloc] init];
response = (NSDictionary *)[responseString JSONValue];
NSLog(#"Response : Promotions %#", response);
if(response != Nil){
if([response count]>0){
arrPromos = [NSMutableArray arrayWithArray:[response objectForKey:#"Promos"]];
NSLog(#"ArrPromos # loading %#", arrPromos);
// create promos galley
[self createPromosGallery];
}
}
}
}
});
Note: [self createPromosGallery]; is calling after download all the images and data.
Create Gallery
-(void) createPromosGallery{
// sort arrPromos based on priority
for(int i=0; i<[arrPromos count];i++){
[arrPromos sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDictionary *dict1 = obj1;
NSDictionary *dict2 = obj2;
NSString *string1;
NSString *string2;
if(![[dict1 objectForKey:#"priority"] isKindOfClass: [NSNull class]])
string1 = [dict1 objectForKey:#"priority"];
if(![[dict2 objectForKey:#"priority"] isKindOfClass: [NSNull class]])
string2 = [dict2 objectForKey:#"priority"];
return [string1 compare:string2 options:NSNumericSearch];
}];
}
NSLog(#"ArrPromos %#", arrPromos);
// scrollView size
CGFloat screenHieght = [UIScreen mainScreen].bounds.size.height;
if(screenHieght>500){
scrollView.frame = CGRectMake(0, 0, 320, 568);
}
else{
scrollView.frame = CGRectMake(0, 0, 320, 480);
}
// define scrollview height
int scrollHieght;
scrollHieght = ([arrPromos count]-1)/2;
NSLog(#"Scroll height %d",scrollHieght);
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width , scrollHieght * 160 +200);
scrollView.pagingEnabled = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.decelerationRate = UIScrollViewDecelerationRateFast;
scrollView.delegate = self;
for(int i=0;i<[arrPromos count];i++)
{
float x;
float y;
if(i%2==0)
{
x=30.0;
y=(i/2)*160+25;
}
if(i%2==1) {
x=170.0;
y=(i/2)*160+25;
}
// retreive saved images
NSString *strImgName;
UIImage *buttonUpImage;
// create buttons
button = [UIButton buttonWithType:UIButtonTypeCustom];
strImgName = [[arrPromos objectAtIndex:i] objectForKey:#"image"];
NSLog(#"Button image name %#", strImgName);
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
NSString *docDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#",docDirectory,strImgName];
buttonUpImage = [UIImage imageWithContentsOfFile:filePath];
[button setBackgroundImage:buttonUpImage forState:UIControlStateNormal];
button.frame = CGRectMake(x, y, 120,140);
[button setTag:i];
[button addTarget:self action:#selector(promoBtnPressed:)forControlEvents:UIControlEventTouchUpInside];
[self.scrollView addSubview:button];
}
}
Note: I tested on both iOS 7 and 6. In iOS 7, it takes very long time to appear images on scrollView(Currently have only 2 images). Or else, If I TAP on scroolView then the images appear.
In ios 6, nothing appear
//Make a method that has url (fileName) Param
NSArray *documentsDirectory =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSFileManager *fileManager =[NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:textPath])
{
return YES;
}
else
{
return NO;
}
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage
imageNamed:#""]];//Placeholder image
if ([url isKindOfClass:[NSString class]])
{
imgView.image = [UIImage imageNamed:[url absoluteString]];
imgView.contentMode = UIViewContentModeScaleAspectFit;
}
else if ([fileManager fileExistsAtPath:url])
{
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSError *error = nil;
NSData *fileData = [NSData dataWithContentsOfFile:textPath options:NSDataReadingMappedIfSafe error:&error];
if (error != nil)
{
DLog(#"There was an error: %#", [error description]);
imgView.image=nil;
}
else
{
imgView.image= [UIImage imageWithData:fileData]
}
}
else
{ UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
CGPoint center = imgView.center;
// center.x = imgView.bounds.size.width / 2;
spinner.center = center;
[spinner startAnimating];
[imgView addSubview:spinner];
dispatch_queue_t downloadQueue = dispatch_queue_create("iamge downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner removeFromSuperview];
UIImage *image = [UIImage imageWithData:imgData];
NSError *error = nil;
[imgData writeToFile:url options:NSDataWritingFileProtectionNone error:&error];
if (error != nil)
}
else
{
}
imgView.image = image;
});
});
}
Thats UIImageView loading an image if it doesnot exist in document then it Save it , An Activity indicator is added to show image is loading to save,
Yes it is because you are downloading and then saving the images which takes time. I suggest you to use any library for downloading images and saving them.
Ex : SDWebImage