Here is my code, please help. In the below I need to get the time taken to load image from url and display the time in custom tableview cell. Which we can use either NSTimer or NSDate.
Thanks in advance.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
TableViewCell *cell = (TableViewCell *)[_tableViewUsername dequeueReusableCellWithIdentifier:CellIdentifier];
NSDate *object = arrURL[indexPath.row];
rowCount = indexPath.row;
cell.userName.text = [arrUserNames objectAtIndex:indexPath.row];
if ([object valueForKey:#"status"])
{
if([[object valueForKey:#"status"]isEqualToString:#"completed"] && [object valueForKey: #"image"] && [[object valueForKey: #"image"] isKindOfClass:[UIImage class]])
{
cell.customImageView.contentMode = UIViewContentModeScaleToFill;
cell.customImageView.image = [object valueForKey:#"image" ];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
else
{
[object setValue:#"inprogress" forKey:#"status"];
[self.operationQueue addOperationWithBlock:^
{
UIImage * image = [UIImage imageWithData:[NSData dataWithContentsOfURL:
[NSURL URLWithString:[object valueForKey:#"url"]]]];
[object setValue:image forKey:#"image"];
[object setValue:#"completed" forKey:#"status"];
//count set
[[NSOperationQueue mainQueue] addOperationWithBlock:^
{
[_tableViewUsername reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
}];
}];
}
return cell;
}
You can use following code. But for this you have to use SDWebImageCache
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cellId"];
__block NSDate *startTime = [NSDate date];
[cell.nImageView sd_setImageWithURL:[NSURL URLWithString:[imageUrlArray objectAtIndex:indexPath.row]] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
NSDate *endTime = [NSDate date];
NSTimeInterval secs = [endTime timeIntervalSinceDate:startTime];
NSLog(#"Seconds (%ld) --------> %f",(long)indexPath.row, secs);
}];
return cell;
}
To download SDWebImage Use this link
Define below method in your .m file
- (void)downloadImageFrom:(NSString *)strURL response:(void (^)(NSData *data))handler
{
strURL = [strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:strURL]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (data)
{
handler(data);
}
}];
}
And call from cellForRowAtIndexpath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomCell";
TableViewCell *cell = (TableViewCell *)[_tableViewUsername dequeueReusableCellWithIdentifier:CellIdentifier];
NSDate *object = arrURL[indexPath.row];
rowCount = indexPath.row;
cell.userName.text = [arrUserNames objectAtIndex:indexPath.row];
cell.customImageView.contentMode = UIViewContentModeScaleToFill;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self downloadImageFrom:[object valueForKey:#"url"] response:^(NSData *data) {
if (data)
{
cell.customImageView.image = [[UIImage alloc] initWithData:data];
}
}];
}
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];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"cell";
TVcell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[TVcell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.titleLabel.text = [[[arrayData objectAtIndex:indexPath.row]valueForKey:#"title"]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.txtlabel.text = [[[arrayData objectAtIndex:indexPath.row] valueForKey:#"description"]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.tag = indexPath.row;
cell.imageView.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[enclosureUrlArray objectAtIndex:indexPath.row]]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
cell.IMGLabel.image = image;
[cell setNeedsLayout];
}
});
}
});
return cell;
}
while i'm scrolling that same images are appearing on the cells,which cells im reusing.i used scroll view delegate also.im storing urls in enclosureUrlArray and i'm passing.
Put cell.IMGLabel.image = nil in your cellForRowAtIndexPath before downloading image, i.e. below cell.imageView.image = nil; this line.
Or set some place holder image (no image available kind of image to cell's image in interface builder), so if image is not downloaded then it will show this place holder image otherwise it will show downloaded image.
SDWebImage is good for this kind of case. It will cache the images so it will give better performance also. There is nothing wrong to use any good third party library.
By using SDWeb image:
#import <SDWebImage/UIImageView+WebCache.h>
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided sd_setImageWithURL: method to load the web image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
cell.textLabel.text = #"My Text";
return cell;
}
You can also use NSURLSession as well,see this link
Async image loading from url inside a UITableView cell - image changes to wrong image while scrolling
NSURL *url = [NSURL URLWithString:[enclosureUrlArray objectAtIndex:indexPath.row]];
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 *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
if (updateCell)
updateCell.IMGLabel.image = image;
});
}
}
}];
[task resume];
works perfect for me..
with the help of sdwebimage you can show the image like this:-
NSString *string2 = [[businessListArray objectAtIndex:indexPath.row ]valueForKey:#"logo"];
NSURL *url1 = [NSURL URLWithString:
[NSString stringWithFormat:
#"%#%#",
#"http://dev-demo.info.bh-in-15./upload/post/",
string2]];
UIImageView *imageView = (UIImageView *)[cell.contentView viewWithTag:301];
[imageView sd_setImageWithURL:url1
placeholderImage:[UIImage imageNamed:#"pocket.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
imageView.image = image;
}];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{ static NSString *CellIdentifier = #"cell";
TVcell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
cell = [[TVcell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.txtlabel.text = [[[arrayData objectAtIndex:indexPath.row] valueForKey:#"description"]stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.IMGLabel.contentMode = UIViewContentModeScaleAspectFill;
cell.IMGLabel.image = nil;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[enclosureUrlArray objectAtIndex:indexPath.row]]];
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(), ^{
cell.IMGLabel.image = image;
[cell.IMGLabel setImage:image];
[cell.IMGLabel.layer setMasksToBounds:YES];
[cell.IMGLabel.layer setCornerRadius:2.5f];
[cell setNeedsLayout];
});
}
}
}];
[task resume];
Your problem is that you have no guarantee that your NSUrlRequests will terminate in the same order than they started. This is bad because your cells are re-used for better performance and it can end with strange behavior.
You can find a fix here: Asynchronous downloading of images for UITableView with GCD
Or you can use tools listed here to help you address this issue: https://stackoverflow.com/a/32601838/3769338
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
I have 5 types of Custom UITableViewCell . I am having numberofrows also correct. But when it comes to display. The last 2 cells are getting over each other .
This is the method i am using to display the cells for the indexpath row. every if statement is working properly. as i checked with NSlog in it .
if (indexPath.row == 0) {
TaskDetailTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TaskDetail" forIndexPath:indexPath];
[cell.assignTo setText:#" Lalu • Aug 30 , 2014 "];
[cell.taskname setText:task_name];
[cell.comments_countLbl setText:comments_count];
// Configure the cell...
NSLog(#"Cell Type %#",#"Task Detail");
return cell;
}
else if (![comments[indexPath.row] isEqual:[NSNull null]] && ![imagecomments[indexPath.row] isEqual:[NSNull null]]) {
Image_Text_Commet_TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"image_text_comment" forIndexPath:indexPath];
[cell.commentText setText:[comments objectAtIndex:indexPath.row]];
NSString *imageURL = [imagecomments objectAtIndex:indexPath.row];
NSString *convertURltoImage = [NSString stringWithFormat:#"%#%#",#"http://localhost:3001/",imageURL];
NSURL *url = [NSURL URLWithString:convertURltoImage];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
UIImage *placeholderImage = [UIImage imageNamed:#"placeholder"];
__weak Image_Text_Commet_TableViewCell *weakCell = cell;
[cell.imageComment setImageWithURLRequest:request
placeholderImage:placeholderImage
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.imageComment.image = image;
[weakCell setNeedsLayout];
} failure:nil];
NSLog(#"Cell Type %#",#"Image and Text");
return cell;
}
else if (![imagecomments[indexPath.row] isEqual:[NSNull null]] && [comments[indexPath.row] isEqual:[NSNull null]]){
ImageCommentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ImageComment" forIndexPath:indexPath];
NSString *imageURL = [imagecomments objectAtIndex:indexPath.row];
NSString *convertURltoImage = [NSString stringWithFormat:#"%#%#",#"http://localhost:3001/",imageURL];
NSURL *url = [NSURL URLWithString:convertURltoImage];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
UIImage *placeholderImage = [UIImage imageNamed:#"placeholder1"];
__weak ImageCommentTableViewCell *weakCell = cell;
[cell.imageComment setImageWithURLRequest:request
placeholderImage:placeholderImage
success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
weakCell.imageComment.image = image;
[weakCell setNeedsLayout];
} failure:nil];
NSLog(#"Cell Type %#",#"Image Only");
return cell;
}
else if ([imagecomments[indexPath.row] isEqual:[NSNull null]] && ![comments[indexPath.row] isEqual:[NSNull null]]){
CommentTaskTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"commentText" forIndexPath:indexPath];
[cell.memberComment setText:[comments objectAtIndex:indexPath.row]];
NSLog(#"Cell Type %#",#"Text Only");
return cell;
}
else {
AddCommentTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Addcomment" forIndexPath:indexPath];
NSLog(#"Cell Type %#",#"Add Task Only")![This is the method i am using to display the cells for the indexpath row. every if statement is working properly. as i checked with NSlog in it .][3];
return cell;
}
you need to set the height of cell dynamically that may be the problem
use this method:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat rowHeight = [self getRowHeightForRow: indexPath.row];
return rowHeight;
}