i want to parse an image from web services and show onto the collection view custom cell for this i write a code as
in my .h file
#property(strong,nonatomic)IBOutlet UICollectionView *imagecollection;
#property(strong,nonatomic)NSArray *imagesa;
#property(strong,nonatomic)NSDictionary *json;
#property(strong,nonatomic)NSArray *aimages;
and in my .m file
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)
#define imageURL [NSURL URLWithString:#"http://www.truemanindiamagazine.com/webservice/gallery_image.php"]
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL: imageURL];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
[self.imagecollection registerNib:[UINib nibWithNibName:#"Custumcell" bundle:nil] forCellWithReuseIdentifier:#"CellIdentifier"];
}
-(void)fetchedData:(NSData *)responsedata
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
self.imagesa=[json objectForKey:#"data"];
NSLog(#"images,%#",self.imagesa);
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return self.imagesa.count;
}
-(Custumcell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Custumcell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier" forIndexPath:indexPath];
UIImageView *img=[[UIImageView alloc]initWithFrame:CGRectMake(0,0,100,100)];
NSString *img2=[self.imagesa objectAtIndex:indexPath.row];
img.image=[UIImage imageNamed:img2];
cell.imageview.image=[UIImage imageNamed:img2];
return cell;
}
then images from web services is parsed but not shown into the collection view please give me any solution.
try to replace your
-(void)fetchedData:(NSData *)responsedata
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
self.imagesa=[json objectForKey:#"data"];
NSLog(#"images,%#",self.imagesa);
}
with the code
-(void)fetchedData:(NSData *)responsedata
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
self.imagesa=[json objectForKey:#"data"];
if (self.imagesa.count) {
dispatch_async(dispatch_get_main_queue(), ^{
[imagecollection reloadData];
});
}
NSLog(#"images,%#",self.imagesa);
}
now use SDWebImageDownloader and inside your cellForRowAtIndexpath method, replace your method cellForRowAtIndexPath with
Custumcell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier" forIndexPath:indexPath];
NSDictionary *dict = [self.imagesa objectAtIndex:indexPath.item];
NSString *img2=[dict valueForKey:#"link"];
[cell.imageview sd_setImageWithURL:[NSURL URLWithString:[img2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:[UIImage imageNamed:#"temp.png"] options:SDWebImageProgressiveDownload completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"downloaded");
});
}];
return cell;
also import #import "UIImageView+WebCache.h" in your file
May be this will help you.
#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
-(Custumcell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
Custumcell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:#"CellIdentifier" forIndexPath:indexPath];
cell.imageview.image= nil; // or cell.poster.image = [UIImage imageNamed:#"placeholder.png"];
dispatch_async(kBgQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.imagesa objectAtIndex:indexPath.row] objectForKey:#"link"]]];
if (imgData) {
UIImage *image = [UIImage imageWithData:imgData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
Custumcell *updateCell = (id)[collectionView cellForItemAtIndexPath:indexPath];
if (updateCell)
updateCell.imageview.image = image;
});
}
}
});
return cell;
}
Related
I want to design as like image. I use two UICollectionView to design. But I can't update second UICollectionView data after click fast on UICollectionview row. I never think this is the correct way to do this. Any suggestion please. I need to do with Objective-C.
My Code:
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
{
if (view.tag == 1) {
return 20;//SelfiThemeIm;age.count
} else {
return 15;
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (cv.tag == 0) {
TopCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"TopCell" forIndexPath:indexPath];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: SelfiThemeImage[indexPath.row]]];
cell.imageView.image = [UIImage imageWithData: imageData];
return cell;
} else {
BottomCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"BottomCell" forIndexPath:indexPath];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: SelfiThemePhysicalFileName[indexPath.row]]];
cell.imageView.image = [UIImage imageWithData: imageData];
return cell;
}
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *ThemeURL;
if (collectionView.tag == 1) {
ThemeURL = #"http://wap.shabox.mobi/sticker_app_server/content.aspx?catid=";
ThemeURL =[ThemeURL stringByAppendingString:[SelfiThemeImageContentCode objectAtIndex:indexPath.row]];
BottomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"BottomCell" forIndexPath:indexPath];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:ThemeURL
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *array= [responseObject objectForKey:#"stickers"];
self.selfidata = array;
// NSLog(#"JSON responce Selfi: %#", self.selfidata);
for(int i=0; i<=self.selfidata.count-1; i++){
NSString *PhysicalFileName = #"http://wap.shabox.mobi/CMS/content/graphics/Stickers/D200x200/";
PhysicalFileName =[PhysicalFileName stringByAppendingString:[[self.selfidata objectAtIndex:i]objectForKey:#"PhysicalFileName"]];
PhysicalFileName =[PhysicalFileName stringByAppendingString:#".png"];
[SelfiThemePhysicalFileName addObject:[NSString stringWithFormat:PhysicalFileName]];
NSLog(#"PhysicalFileName Array - %#", PhysicalFileName);
}
NSLog(#"SelfiThemePhysicalFileName Array - %#", SelfiThemePhysicalFileName);
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: SelfiThemePhysicalFileName[indexPath.row]]];
cell.imageView.image = [UIImage imageWithData: imageData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}else{
}
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section
{
if (view.tag == 1) {
return SelfiThemeImage.count;
} else {
return SelfiThemePhysicalFileName.count;
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
if (cv.tag == 0) {
TopCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"TopCell" forIndexPath:indexPath];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: SelfiThemeImage[indexPath.row]]];
cell.imageView.image = [UIImage imageWithData: imageData];
return cell;
} else {
BottomCell *cell = [cv dequeueReusableCellWithReuseIdentifier:#"BottomCell" forIndexPath:indexPath];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: SelfiThemePhysicalFileName[indexPath.row]]];
cell.imageView.image = [UIImage imageWithData: imageData];
return cell;
}
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *ThemeURL;
if (collectionView.tag == 1) {
ThemeURL = #"http://wap.shabox.mobi/sticker_app_server/content.aspx?catid=";
ThemeURL =[ThemeURL stringByAppendingString:[SelfiThemeImageContentCode objectAtIndex:indexPath.row]];
BottomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"BottomCell" forIndexPath:indexPath];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:ThemeURL
parameters:nil
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *array= [responseObject objectForKey:#"stickers"];
self.selfidata = array;
// NSLog(#"JSON responce Selfi: %#", self.selfidata);
for(int i=0; i<=self.selfidata.count-1; i++){
NSString *PhysicalFileName = #"http://wap.shabox.mobi/CMS/content/graphics/Stickers/D200x200/";
PhysicalFileName =[PhysicalFileName stringByAppendingString:[[self.selfidata objectAtIndex:i]objectForKey:#"PhysicalFileName"]];
PhysicalFileName =[PhysicalFileName stringByAppendingString:#".png"];
[SelfiThemePhysicalFileName addObject:[NSString stringWithFormat:PhysicalFileName]];
NSLog(#"PhysicalFileName Array - %#", PhysicalFileName);
}
NSLog(#"SelfiThemePhysicalFileName Array - %#", SelfiThemePhysicalFileName);
[self.myCollectionView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}else{
}
}
I made changes in your code that just replace it with your code .
Happy Coding. give vote and approve it
Thank You.
You need have 2 objects referring CollectioView lets say _collectionView1 and _collectionView1.
Now make sure delegate for these 2 is set to self
in -(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath check
if ([collectionView isEqualTo:_collectionView1]) {
_collectionView2DataSource = ;//Do your calculation and setting
[_collectionView2 reloadData] ;
}
I am considering you have populated initial value and you are aware of all collection-view datasource and delegate functioning.
If you have the 2nd collectionview in storyboard/xib file, create the IBOUTLET for that collectionview and name it "what_ever_name_you_want"
if you have created this programatically, make the collectionview a global variable in the class
in didSelect method reload the collection view by calling ["what_ever_name_you_gave" reloadData];
you need to change this line because this line create new cell instance .
BottomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"BottomCell" forIndexPath:indexPath];
change with :
BottomCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
cell =[self.imgCllvw dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
if(!cell)
{
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
}
NSDictionary *tmpDict = [images objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:#"img"]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *imge= [[UIImage alloc]initWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
cell.imageView.image = imge;
});
});
cell.layer.borderWidth=1.0f;
cell.layer.borderColor=[UIColor colorWithRed:215.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0].CGColor;
return cell;
}
First image is not loaded and if I scroll the collectionview images are displayed and I have used autolayout for collectionview
I think you should try async downloading of image rather than sync, something like this
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
cell =[self.imgCllvw dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
if(!cell)
{
cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
}
NSDictionary *tmpDict = [images objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:#"img"]];
NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (data) {
UIImage *image = [UIImage imageWithData:data];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
MyCell *cell = (id)[collectionView cellForItemAtIndexPath:indexPath];
if (cell)
cell.imageView.image = image;
});
}
}
}];
[task resume];
cell.layer.borderWidth=1.0f;
cell.layer.borderColor=[UIColor colorWithRed:215.0/255.0 green:214.0/255.0 blue:214.0/255.0 alpha:1.0].CGColor;
return cell;
}
Instead of dispatch_async, mainqueue you can use dispatch_sync, like this,
dispatch_sync(dispatch_get_main_queue(), ^{
cell.imageView.image = imge;
});
In the below code whenever I am scrolling the tableview, images in each cell are changing, which shouldn't happen. Please help. Thanks in advance.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UserDetails *userDetails = [arrUserDetails objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"CustomCell";
__weak TableViewCell *cell = (TableViewCell *)[_tableViewUsername dequeueReusableCellWithIdentifier:CellIdentifier];
cell.tag = indexPath.row;
cell.userName.text = userDetails.userName;
[self.operationQueue addOperationWithBlock: ^ {
NSURL *aURL = [NSURL URLWithString:userDetails.userImageURL];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:aURL options:nil error:&error];
UIImage *image = nil;
if (cell.tag == indexPath.row)
{
image = [UIImage imageWithData:data];
[[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
cell.customImageView.image = image;
cell.customImageView.contentMode = UIViewContentModeScaleToFill;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}];
}
}];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UserDetails *userDetails = [arrUserDetails objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"CustomCell";
__weak TableViewCell *cell = (TableViewCell *)[_tableViewUsername dequeueReusableCellWithIdentifier:CellIdentifier];
cell.tag = indexPath.row;
cell.userName.text = userDetails.userName;
//Add Default placeholder
cell.customImageView.image = [UIImage imageNamed:#"Default.png"];
[self.operationQueue addOperationWithBlock: ^ {
NSURL *aURL = [NSURL URLWithString:userDetails.userImageURL];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:aURL options:nil error:&error];
UIImage *image = nil;
if (cell.tag == indexPath.row)
{
image = [UIImage imageWithData:data];
[[NSOperationQueue mainQueue] addOperationWithBlock: ^ {
cell.customImageView.image = image;
cell.customImageView.contentMode = UIViewContentModeScaleToFill;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}];
}
}];
Add Default placeholder for image before loading it from url,As cells are being reused it takes the previous image
You can use SDWebImage.framework to load image
[cell.customImageView sd_setImageWithURL:[NSURL URLWithString:userDetails.userImageURL] placeholderImage:nil options:SDWebImageCacheMemoryOnly completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (image) {
[cell.customImageView setImage:image];
}
}];
You can use Afnetworking class for this .
Simply import #import "UIImageView+AFNetworking.h"
And use this line:-
[cell.imgProfile setImageWithURL:imgurl placeholderImage:[UIImage imageNamed:#""]];
Imgurl is the image Url which you are getting from response
Good morning,
I'm using UICollectionView for the first time to show images from a user (like a Facebook profile) and at the moment I can show the images fine but I have some problems:
1- When I visit my profile the app freezes for like 2-3 minutes due to the load of 5 images.
2- When I'm moving through the UICollectionView it freezes when the app load again the images outside the screen.
What I have to do in order to not to freeze the app when loading the user pictures? And what I have to do to navigate through the CollectionView without freezing? Maybe a cache system is what I need?
That's my code:
ProfileViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
[self.view setBackgroundColor: [self colorWithHexString:#"FFFFFF"]];
self.profileimage.layer.cornerRadius = self.profileimage.frame.size.width / 2;
self.profileimage.clipsToBounds = YES;
self.profileimage.layer.borderWidth = 1.0f;
self.profileimage.layer.borderColor = [UIColor whiteColor].CGColor;
[self fetchJson];
[self fetchImages];
self.oneCollectionView.dataSource = self;
self.oneCollectionView.delegate = self;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
return 1;
}
-(NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView
{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _carImages.count;
}
// COLLECTION VIEW
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCollectionViewCell *myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:#"MyCell"
forIndexPath:indexPath];
NSString *data = [[_jsonArray objectAtIndex:indexPath.row] valueForKey:#"imagen"];
NSURL * imageURL = [NSURL URLWithString:data];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage * images = [UIImage imageWithData:imageData];
myCell.imageview.image = images;
return myCell;
}
-(void)fetchImages {
self.carImages = [[NSMutableArray alloc] init];
NSString *usersPassword = [SSKeychain passwordForService:#"login" account:#"account"];
NSString * urlString = [NSString stringWithFormat:#"http://mywebsite.com/posts.php?usersPassword=%#",usersPassword];
NSURL * url = [NSURL URLWithString:urlString];
NSData * data = [NSData dataWithContentsOfURL:url];
NSError *error;
[_jsonArray removeAllObjects];
_jsonArray = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
error:&error];
for(int i=0;i<_jsonArray.count;i++)
{
NSDictionary * jsonObject = [_jsonArray objectAtIndex:i];
NSString* imagen = [jsonObject objectForKey:#"imagen"];
[_carImages addObject:imagen];
}
}
Thanks in advance.
Import UIImageView+AFNetworking.h
and load your image via this method in cellForItemAtIndexPath method
[imageView setImageWithURL:[NSURL URLWithString:#"https://lh6.googleusercontent.com/-B8kSXtoaQDo/VGTVlXyIXpI/AAAAAAAAJ_M/USh6SgvMemw/w1024-h1024/IMG_20141112_103152.jpg"] placeholderImage:[UIImage imageNamed:#"placeholder-avatar"]];
it will surely speed up to load and scrolling collectionView
Download the images asynchronously, dataWithContentsOfURL is synchronous method and it will block your current thread until the download completes. You can use libraries like SDWebImage to automatically handle downloading for you or You can use NSURLSessionDownloadTask to download Images.
- (void)fetchImages {
self.carImages = [[NSMutableArray alloc] init];
NSString *usersPassword = [SSKeychain passwordForService:#"login" account:#"account"];
NSString * urlString = [NSString stringWithFormat:#"http://mywebsite.com/posts.php?usersPassword=%#",usersPassword];
NSURL * url = [NSURL URLWithString:urlString];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
[self.jsonArray removeAllObjects];
self.jsonArray = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves
error:&error];
for(int i=0;i<_jsonArray.count;i++)
{
NSDictionary * jsonObject = self.jsonArray[i];
NSString* imagen = jsonObject[#"imagen"];
[self.carImages addObject:imagen];
}
}
}];
[dataTask resume];
}
// COLLECTION VIEW
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCollectionViewCell *myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:#"MyCell"
forIndexPath:indexPath];
NSString *data = [[self.jsonArray objectAtIndex:indexPath.row] valueForKey:#"imagen"];
NSURL * imageURL = [NSURL URLWithString:data];
NSURLSessionDownloadTask *imageDownloadTask = [[NSURLSession sharedSession]
downloadTaskWithURL:imageURL completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
UIImage *image = [UIImage imageWithData:
[NSData dataWithContentsOfURL:location]];
myCell.imageview.image = image;
}];
[imageDownloadTask resume];
return myCell;
}
You can use the dispatcher to create an async operation for the download of the images. This will resolve the 2 problems you have:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imgData = [NSData dataWithContentsOfURL:YOUR_IMAGE_URL];
UIImage *img = [UIImage imageWithData:imgData];
[YOUR_IMAGE_VIEW_OUTLET performSelectorOnMainThread:#selector(setImage:) withObject:img waitUntilDone:YES];
});
These are the snippet you have to change:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCollectionViewCell *myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:#"MyCell"
forIndexPath:indexPath];
NSString *data = [[_jsonArray objectAtIndex:indexPath.row] valueForKey:#"imagen"];
NSURL * imageURL = [NSURL URLWithString:data];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL: imageURL];
UIImage *img = [UIImage imageWithData:imageData];
[myCell.imageview performSelectorOnMainThread:#selector(setImage:) withObject:img waitUntilDone:YES];
});
return myCell;
}
Try to Register Nib For Collection View
Write following code in your viewController's viewDidLoad()method :
UINib *nib = [UINib nibWithNibName:#"MyCollectionCell" bundle: nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:#"Cell"];
And I think you have to use https://github.com/nicklockwood/AsyncImageView for the image loading in collection view.
For Storyboards you have to see this tutorial : http://www.appcoda.com/ios-programming-uicollectionview-tutorial/ This will help you more.
Thanks!
For the first question the answer is in this line of code:
NSData * data = [NSData dataWithContentsOfURL:url];
From Apple Reference:
Do not use this synchronous method to request network-based URLs. For
network-based URLs, this method can block the current thread for tens
of seconds on a slow network, resulting in a poor user experience, and
in iOS, may cause your app to be terminated.
As alternative you can use NSURLSessionDataTask to download data (see Apple Reference)
-Edit
In ProfileViewController.h add these two properties:
#property (nonatomic, strong) NSURLSessionConfiguration *sessionConfig;
#property (nonatomic, strong) NSURLSession *session;
then, in - viewDidLoad initialise them:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view
self.sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
self.session = [NSURLSession sessionWithConfiguration:self.sessionConfig];
//Other stuff...
}
Finally, in ProfileViewController.m
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
MyCollectionViewCell *myCell = [collectionView
dequeueReusableCellWithReuseIdentifier:#"MyCell"
forIndexPath:indexPath];
NSString *data = [[_jsonArray objectAtIndex:indexPath.row] valueForKey:#"imagen"];
NSURL * imageURL = [NSURL URLWithString:data];
NSURLSessionDownloadTask *imageDownloadTask = [self.session dataTaskWithURL:imageURL
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(#"ERROR: %#", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200) {
UIImage *image = [UIImage imageWithData:data];
myCell.imageview.alpha = 0.0f;
myCell.imageview.image = image;
[UIView animateWithDuration:0.45 animations:^{
myCell.imageview.alpha = 1.0f;
});
} else {
NSLog(#"Couldn't load image at URL: %#", imageURL);
NSLog(#"HTTP %d", (int)httpResponse.statusCode);
}
}
}];
[imageDownloadTask resume];
return myCell;
}
I hope this can help you.
- Edit 2
For future readers, I slightly refactored my code based on #suhit's answer (+1 for him)
I made an application that use JSON Data and WebServices containing more pages when I scroll the UITableView. This fetches and displays the next set of data. Next page consists of 10 sets of data. But I only want to show 5 of them. How is it possible? If possible, please share the code.
Here's my code :
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
pageNum = pageNum + 1;
[self getData];
}
-(void)getData
{
NSURL * url=[NSURL URLWithString:[NSString stringWithFormat:#"http://www.truemanindiamagazine.com/webservice/news.php?page=%d",pageNum]];
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL:url];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
And fetch data method code :
-(void)fetchedData:(NSData *)responsedata
{
if (responsedata.length > 0)
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
if ([[_json objectForKey:#"data"] isKindOfClass:[NSArray class]])
{
NSArray *arr = (NSArray *)[_json objectForKey:#"data"];
[self.imageArray addObjectsFromArray:arr];
[self.newsTable reloadData];
NSLog(#"images,%#",self.imageArray);
}
}
[self.spinner stopAnimating];
self.spinner.hidesWhenStopped=YES;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return self.imageArray.count;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
And Remaining Code is :
{
[super viewDidLoad];
pageNum=0;
self.imageArray =[[NSMutableArray alloc]init];
NSURL * url=[NSURL URLWithString:[NSString stringWithFormat:#"http://www.truemanindiamagazine.com/webservice/news.php?page=%d",pageNum]];
[self.newsTable setShowsHorizontalScrollIndicator:NO];
[self.newsTable setShowsVerticalScrollIndicator:NO];
SDWebImageManager.sharedManager.imageDownloader.maxConcurrentDownloads = 3;
SDWebImageManager.sharedManager.imageDownloader.executionOrder = SDWebImageDownloaderLIFOExecutionOrder;
dispatch_async(kBgQueue, ^{
data = [NSData dataWithContentsOfURL: url];
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
});
}
}
-(CustumCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *Cellidentifier=#"Cell";
CustumCell *cell=[tableView dequeueReusableCellWithIdentifier:Cellidentifier];
if (cell ==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustumCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
{
[cell.spinner startAnimating];
NSDictionary *dict = [self.imageArray objectAtIndex:indexPath.section];
NSString *img2=[dict valueForKey:#"post_image"];
[cell.imagePhoto sd_setImageWithURL:[NSURL URLWithString:[img2 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] placeholderImage:[UIImage imageNamed:#"Setting.png"] options:SDWebImageHighPriority completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL)
{
[cell.spinner stopAnimating];
cell.spinner.hidesWhenStopped=YES;
}];
Take a temparary array alloc and try to add the data from the server to this arrray.
Now I do the implementation for this.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if([mTenarray count]==0) {
pageNum = pageNum + 1;
[self getData];
} else {
[self.imageArray addObjectsFromArray:mTenarray];
[mTenarray removeAllObjects];
[self.newsTable reloadData];
}
}
-(void)fetchedData:(NSData *)responsedata
{
if (responsedata.length > 0)
{
NSError* error;
self.json = [NSJSONSerialization JSONObjectWithData:responsedata options:kNilOptions error:&error];
if ([[_json objectForKey:#"data"] isKindOfClass:[NSArray class]])
{
NSArray *arr = (NSArray *)[_json objectForKey:#"data"];
[self.mTenarray addObjectsFromArray:arr];
NSArray *mfivedatarray = [self.mTenarray subarrayWithRange:NSMakeRange(0, 5)];
[self.imageArray addObjectsFromArray:mfivedatarray];
self.mTenarray // remove first five objects
[self.newsTable reloadData];
NSLog(#"images,%#",self.imageArray);
}
}
[self.spinner stopAnimating];
self.spinner.hidesWhenStopped=YES;
}
In some place I wrote the concept to implement