unable to use objectAtIndex property - ios

im trying to load a set of images from web and display it on the screen within a collection view. Following is my code
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
cell.layer.cornerRadius = 5;
NSURL *url = [NSURL URLWithString:
#"http://elatewiki.org/images/thumb/Google.png/120px-Google.png"];
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
//recipeImageView.image = [UIImage imageNamed:[recipePhotos objectAtIndex:indexPath.row] ];
recipeImageView.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:recipPhotoUrl[0] ]];
return cell;
}
but i have to use the objectAtIndex:indexPath.row property along with imageWithData so the image can be swiped . Is there any ways through which i can use objectAtIndex:indexPath.row along with NSData dataWithContentsOfURL ?

You can use this:
NSString *url_str = [NSString stringWithFormat: #"%#",[recipPhotoUrl objectAtIndex: indexPath.item]];
NSURL *url = [NSURL urlWithString:url_str];
recipeImageView.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];

What's the for?
NSURL *url = [NSURL URLWithString:
#"http://elatewiki.org/images/thumb/Google.png/120px-Google.png"];
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
Anyway, you were close to solution....
if (recipPhotoUrl.count > indexPath.row)
{
recipeImageView.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:recipPhotoUrl[indexPath.row]]];
}
But still, you are doing this operations on the main thread and you, for sure, block the UI, the scroll will not be smooth.
It also not so sure as you're accessing the index without checking if the array has a sufficient dimension.

UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];
should be placed in a common function.For example -(void)viewDidLoad, add a property reference to image .
recipeImageView.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:recipPhotoUrl[0]]];
change to
recipeImageView.image = self.image;

Related

why same images are appearing while im scrolling my tabelview cell?

NSString *url = [NSString stringWithFormat:#"%#",[enclosureUrlArray objectAtIndex:indexPath.row]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
([self.tableView cellForRowAtIndexPath:indexPath]);
dispatch_async(dispatch_get_main_queue(), ^{
cell.tag = indexPath.row;
UIImage *image = [UIImage imageWithData:imageData];
cell.IMGLabel.image = image;
[cell.IMGLabel setImage:image];
[cell.IMGLabel.layer setMasksToBounds:YES];
[cell.IMGLabel.layer setCornerRadius:2.5f];
[cell setNeedsLayout];
});
});

Image not showing using Nsurlconnection Post method

I am using nsurlconnection in POST method and created four array for "see","buy","updated","image".Displayed in tableviewcell but "image" not showing. image in "url in png format".
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError* error;
json = [NSJSONSerialization JSONObjectWithData: mutableData
options:kNilOptions
error:&error];
NSLog(#"%#",json);
sellArray = [json valueForKeyPath:#"BranchByList.sell"];
buyArray = [json valueForKeyPath:#"BranchByList.buy"];
updataedArray = [json valueForKeyPath:#"BranchByList.updated"];
imageArray = [json valueForKeyPath:#"BranchByList.flag_image"];
[_datad reloadData];
}
tableview delegate methods are:
-(NSInteger)numberOfSectionsInTableView:(UITableView *) tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section{
return [sellArray count];
return [buyArray count];
return [updataedArray count];
return [imageArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
TableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:#"path" forIndexPath:indexPath];
cell.sellbl.text=[sellArray objectAtIndex:indexPath.row];
cell.buylbl.text=[buyArray objectAtIndex:indexPath.row];
cell.updatedlbl.text = [updataedArray objectAtIndex:indexPath.row];
cell.imglbl.image = [UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]];
return cell;
}
-(void)tableView: (UITableView *) tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
}
You are directly assigning url to image! That will not work at all.
You need to first add the url to NSUrl and then convert the url in to data by using NSData and then assign the data to the image.
To accomplish it add below line of code in your code:
NSURL *url = [NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]];
NSData *data = [NSData dataWithContentsOfURL:url];
cell.imglbl.image = [UIImage imageWithData:data];
I'm posting one more example for more understanding. I have a url and i need to display the image from that url to my device. For that m using the below line of code:
NSURL *url = [NSURL URLWithString:#"http://1.bp.blogspot.com/-9yd6LPL2N6U/VatsUdMffPI/AAAAAAAAAl4/Pq1S6Q20fy0/s1600/hello_world.gif"];
NSData *data = [NSData dataWithContentsOfURL:url];
_imgView.image=[UIImage imageWithData:data];
Above url is just a random url of a image taken from google.
Result:
You are calling image like,
cell.imglbl.image = [UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]];
It is fine if image is available in your project otherwise you need to download it from url which you getting in response like,
NSData *data = [NSData dataWithContentsOfURL:#"you url"];
UIImage *img = [UIImage imageWithData:data];
cell.imglbl.image = img;
or you can use SDWebImage, greate third party library to caching the image.
hope this will help :)
Add SDWebImage
in your project and use this code
[cell.imglbl setImageWithURL:[NSURL URLWithString:[imageArray objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
instead of
cell.imglbl.image = [UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]];
return cell;
It seems like you set not an image to cell.imglbl.image, but the url of it..
cell.imglbl.image = [UIImage imageNamed:[imageArray objectAtIndex:indexPath.row]];
You can use some third party library like SDWebImage to asynchronous download image.
https://github.com/rs/SDWebImage
(Or download it synchronous like this
NSData * data = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]];
UIImage *image = [UIImage imageWithData:data];
)
Also I would recommend you to have a Dictionary to keep already downloaded images, where the keys will be the indexPaths of cells.
Hope it help :)

UICollection View cell images are changing while scrolling horizontally

I am using array of url's for images to load in collection view. Images are changing while scrolling the collection view. How to fix this issue?
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"RecentProductCell";
RecentProductCell *recentCell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
recentCell.recentProductImg.image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSString *imageurl = [[latestProducts valueForKey:#"image"]objectAtIndex:indexPath.item];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageurl]];
dispatch_sync(dispatch_get_main_queue(), ^{
recentCell.recentProductImg.image = [UIImage imageWithData:imageData];
});
});
}
Replace dispatch_sync(dispatch_get_main_queue(), ^{
recentCell.recentProductImg.image = [UIImage imageWithData:imageData];
});
with
dispatch_sync(dispatch_get_main_queue(), ^{
if ( imageData )
{
UIImage *urlImage = [[UIImage alloc] initWithData:imageData];
RecentProductCell *recentCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
if (recentCell)
[recentCell.recentProductImg setImage:urlImage];
}
});
Let me know if this works for you.
cell.imageView.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSString *imageurl = [[latestProducts valueForKey:#"image"]objectAtIndex:indexPath.item];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imageurl]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
cell.imageView.image = image;
[cell setNeedsLayout];
}
});
}
});
Write this code in cellForRowAtIndexPath method of collectionView

iOS UIImage Passes Old Image

In my app, Im using an API to get images from a server. Using the below code, it gets the images in order of size to replace themselves with better quality.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *imageURL = [NSURL URLWithString: [NSString stringWithFormat:#"%#", [[[self.information objectForKey:#"images"]objectForKey:#"normal"] description]]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
self.shotImage = [UIImage imageWithData:imageData];
self.image.image = self.shotImage;
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *imageURL = [NSURL URLWithString: [NSString stringWithFormat:#"%#", [[[self.information objectForKey:#"images"]objectForKey:#"hidpi"] description]]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
self.image.image = self.shotImage;
});
Also, if you press on the image it then takes you too another ViewController where the image is fullscreen.
However, even if I wait for the high quality one to load before I tap on it, in the PrepareForSegue Method, it still only passes the original low quality version.
See code below from PrepareForSegue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
FullSizeImageViewController *vc = [segue destinationViewController];
UIImage *img = [[UIImage alloc] init];
img = self.shotImage;
vc.shotImage = img;
}
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *imageURL = [NSURL URLWithString: [NSString stringWithFormat:#"%#", [[[self.information objectForKey:#"images"]objectForKey:#"hidpi"] description]]];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
self.image.image = self.shotImage;
});
In this code looks like you miss this line:
self.shotImage = [UIImage imageWithData:imageData];

Downloading image from a url into a UIImageVIew dynamically

I am trying to insert and image into a UIImageView from a url. I used the following code to do so.
When running the program gets stuck at
NSURL *url = [NSURL URLWithString:urlstring];
In the below code and it shows "Thread 1 : signal SIGABRT" on that particular line.
Can someone help me with this and tell if the format that i used is correct or what i had did wrong??
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"newoffer";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *temp = [product objectAtIndex:indexPath.row];
UILabel *Label = (UILabel *)[cell viewWithTag:201];
Label.text = [temp objectForKey:#"item_name"];
UIImageView *Image = (UIImageView *)[cell viewWithTag:200];
NSString *urlstring=[temp objectForKey:#"image_url"];
NSURL *url = [NSURL URLWithString:urlstring];
NSData *data = [NSData dataWithContentsOfURL:url];
Image.image = [UIImage imageWithData:data];
return cell;
}
Change this code:
NSURL *url = [NSURL URLWithString:urlstring];
NSData *data = [NSData dataWithContentsOfURL:url];
Image.image = [UIImage imageWithData:data];
To:
dispatch_queue_t myqueue = dispatch_queue_create("myqueue", NULL);
// execute a task on that queue asynchronously
dispatch_async(myqueue, ^{
NSURL *url = [NSURL URLWithString:[urlstring stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];;
NSData *data = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
Image.image = [UIImage imageWithData:data]; //UI updates should be done on the main thread
});
});
As mentioned by others, an Image Caching library like SDWebImage will help a lot because even with this implementation, you just push the download process to a background thread so the UI does not get stucked, but you are not caching anything.
Try this
[image setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.vbarter.com/images/content/1/9/19517.jpg"]]]];
For async downloading
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[image setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://www.vbarter.com/images/content/1/9/19517.jpg"]]]];
});
if url is dynamic then
NSString *stringUrl; // this can be any valid url as string
[image setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:stringUrl]]]];
NSData *data = [NSData dataWithContentsOfURL:url];
will load imageData synchronous, that means main thread will be blocked .
Use the project on github:SDWebImage for image asynchronous loading and cache.
There's probably better libraries that do this now, but I have always been using this for my projects and it works well: AsyncImageView. There are other alternatives like SDWebImage
But basically, you don't want to use
NSData *data = [NSData dataWithContentsOfURL:url];
because it will block the main thread until the image is downloaded. To avoid this you might want to use something asynchronous, like the above two libraries.
For example, with AsyncImageView, it becomes as easy as:
myImageView.imageURL = someNSURL;

Resources