Loading gifs into my UITableViewCell using SDWebImage. It's actually really fast, but the tableview doesn't seem to load up until the user actually scrolls the tableview.
Any suggestions for how to fix this issue?
This is my UITableView
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return self.gifArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"Cell";
RDGifGridTableViewCell *cell = (RDGifGridTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"RDGifGridTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.urlLabel.text = [self.gifArray objectAtIndex:indexPath.row];
cell.urlLabel.textColor = [UIColor clearColor];
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:cell.urlLabel.text] placeholderImage:nil options:SDWebImageCacheMemoryOnly];
return cell;
}
This is how I add content to the array which occurs in viewDidLoad:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *idArray = [json objectForKey:#"data"];
for (NSDictionary *ids in idArray) {
NSDictionary *images = ids[#"images"];
NSDictionary *fixedHeightImage = images[#"fixed_width"];
self.gifURL = fixedHeightImage[#"url"];
[self.gifArray addObject:self.gifURL];
[self.tableView reloadData];
}
The following line might be the problem
static NSString *MyIdentifier = #"Cell";
When your cells are being reused you are using a different cellIdentfier RDGifGridTableViewCell.
It should be the same cell being reused.
So just fix this line and use that variable again when it's nil to avoid such mistake, oh and while you're at it, consider renaming your variable to first letter lowercase myIdentifier as Objective C naming convention suggests.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"RDGifGridTableViewCell";
RDGifGridTableViewCell *cell = (RDGifGridTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"RDGifGridTableViewCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.urlLabel.text = [self.gifArray objectAtIndex:indexPath.row];
cell.urlLabel.textColor = [UIColor clearColor];
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:cell.urlLabel.text] placeholderImage:nil options:SDWebImageCacheMemoryOnly];
return cell;
}
Related
I have viewController with tableView, tableView has two prototype cells, second cell has sno, date, amount 3 labels. I created TableViewCell class and i created 3 outlets for this 3 labels in this TableViewCell class. I am getting data from server and i want to assign that data to this 3 labels. How?
In tableViewCell.h
#property (weak, nonatomic) IBOutlet UILabel *serialNumber;
#property (weak, nonatomic) IBOutlet UILabel *dateLabel;
#property (weak, nonatomic) IBOutlet UILabel *amountLabel;
In viewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.displayDataTableView.delegate = self;
self.displayDataTableView.dataSource = self;
self.urlSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
self.urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://"]];
self.dataTask = [self.urlSession dataTaskWithRequest:self.urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableDictionary *serverRes = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
// NSLog(#"...%# ", serverRes);
self.integer = [[serverRes objectForKey:#"Data"] count];
dispatch_async(dispatch_get_main_queue(), ^{
[self.displayDataTableView reloadData];
});
self.dateArray = [[NSMutableArray alloc]init];
self.amountArray = [[NSMutableArray alloc]init];
[self.dateArray addObject:[[[serverRes objectForKey:#"Data"] objectAtIndex:i] objectForKey:#"Date"]];
[self.amountArray addObject:[[[serverRes objectForKey:#"Data"] objectAtIndex:i] objectForKey:#"TotalAmount"]];
}
}];
[self.dataTask resume];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row == 0)
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"detailsCell" forIndexPath:indexPath];
return cell;
}else{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"detailsTitle" forIndexPath:indexPath];
TableViewCell *tvc;
tvc.dateLabel.text = [self.dateArray objectAtIndex:indexPath.row];
NSLog(#"********** = %#", tvc.dateLabel.text);
return cell;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.displayDataTableView reloadData];
});
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0)
{
static NSString *cellIdentifier =#"detailsCell";
// Make Your cell as this
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.dateLabel.text = [self.dateArray objectAtIndex:indexPath.row];
cell.amountLabel.text = [self.amountArray objectAtIndex:indexPath.row];
}
return cell;
}
you need to change class of tableview cell
else{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"detailsTitle" forIndexPath:indexPath];
cell.dateLabel.text = [self.dateArray objectAtIndex:indexPath.row];
// same
cell.amountLabel.text = [self.dateArray objectAtIndex:indexPath.row];
NSLog(#"********** = %#", cell.dateLabel.text);
return cell;
}
or change sequence
self.dateArray = [[NSMutableArray alloc]init];
self.amountArray = [[NSMutableArray alloc]init];
[self.dateArray addObject:[[[serverRes objectForKey:#"Data"] objectAtIndex:i] objectForKey:#"Date"]];
[self.amountArray addObject:[[[serverRes objectForKey:#"Data"] objectAtIndex:i] objectForKey:#"TotalAmount"]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.displayDataTableView reloadData];
});
Use this code
self.dataTask = [self.urlSession dataTaskWithRequest:self.urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableDictionary *serverRes = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
self.dateArray = [[NSMutableArray alloc]init];
self.amountArray = [[NSMutableArray alloc]init];
for (int i = 0; i < [[serverRes objectForKey:#"Data"] count]; i++) {
[self.dateArray addObject:[[[serverRes objectForKey:#"Data"] objectAtIndex:i] objectForKey:#"Date"]];
[self.amountArray addObject:[[[serverRes objectForKey:#"Data"] objectAtIndex:i] objectForKey:#"TotalAmount"]];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.displayDataTableView reloadData];
});
}];
i'm displaying data from a webservice in my tableview app but i get the array twice in the tableview.
also i'm trying to use the endless scroll to show paginated data without success
(void)viewDidLoad {
[super viewDidLoad];
self.articlesArray = [[NSMutableArray alloc] init];
[self fetchData:1];
}
my function to fetch data
-(void) fetchData:(int)page {
NSString *urlString = [NSString
stringWithFormat:#"http://url?page=%d", (int)page];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
NSData *theData = [NSURLConnection sendSynchronousRequest:request
returningResponse:nil
error:nil];
self.articlesArray = [NSJSONSerialization JSONObjectWithData:theData
options:NSJSONReadingMutableContainers
error:nil];
[self.tableView registerNib:[UINib nibWithNibName:#"ArticleCell" bundle:nil] forCellReuseIdentifier:#"ArticleCell"];
}
and here's my tableview methods please see what i did wrong
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section==0)
{
return [self.articlesArray count];
else
return [self.articlesArray count];
}
// return [self.articlesArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger row = [indexPath row];
if (3 == (row % 4)) { // or 0 == if you want the first cell to be an ad!
static NSString *MyIdentifier = #"AdCell";
AdViewCell *cell = (AdViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if ((cell == nil) || (![cell isKindOfClass: AdViewCell.class]))
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"AdCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell = [[AdViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] ;
}
GADBannerView *bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeMediumRectangle];
bannerView.adUnitID =#"";
bannerView.rootViewController =self;
GADRequest *request = [GADRequest request];
[bannerView loadRequest:request];
[cell.contentView addSubview:bannerView];
return cell;
}
else{
static NSString *simpleTableIdentifier = #"ArticleCell";
ArticleViewCell *cell = (ArticleViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier ];
if ((cell == nil) || (![cell isKindOfClass: ArticleViewCell.class]))
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ArticleCell" owner:self options:nil];
cell = [nib objectAtIndex:1];
cell = [[ArticleViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier] ;
}
NSDictionary * tempDictionary = [self.articlesArray objectAtIndex:indexPath.row];
NSString *imageUrl = [[self.articlesArray objectAtIndex:indexPath.row]objectForKey:#"featured_image"];
imageUrl = [imageUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
[cell.thumbnailImageView sd_setImageWithURL:[NSURL URLWithString:imageUrl ] placeholderImage:nil options:SDWebImageRetryFailed completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (image){
// Set your image over here
}else{
//something went wrong
NSLog(#"Error occured : %#", [error description]);
}
}];
NSString * title=[tempDictionary valueForKeyPath:#"title.rendered"];
cell.titleLabel.text = title;
return cell;
}
}
You can remove duplicate values once you get response from json, before reload tableview remove duplicate elements from array
NSOrderedSet *orderedSet = [NSOrderedSet orderedSetWithArray:YourArray];
NSArray *arrayWithoutDuplicates = [orderedSet array];
Thanks
I have a smooth scrolling problem with the UITableView. Can anyone help me where is the problem? The code I have written is this-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
LabTestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}//cell.txtHeading.text=#"hello";
cell.txtHeading.text=[[_ResponseDic valueForKey:#"title"]objectAtIndex:indexPath.row];
cell.txtdescribtion.text=[[_ResponseDic valueForKey:#"description"]objectAtIndex:indexPath.row];
cell.txtPrice.text=[[_ResponseDic valueForKey:#"purchase_price"]objectAtIndex:indexPath.row];
cell.txtLabName.text=[[_ResponseDic valueForKey:#"brand"]objectAtIndex:indexPath.row];
NSString *path=#"https://www.fingerfry.com/pharmgo/uploads/product_image/";
NSString *url=[path stringByAppendingString:[[_ResponseDic valueForKey:#"main_image"]objectAtIndex:indexPath.row]];
NSData* imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
cell.image.image=image;
return cell;
}
If you load the image in cellForRowAtIndexPath, use Asynchronous method backgroundly load the images, use this below code,
dispatch_queue_t image_queue = dispatch_queue_create("com.company.app.imageQueue", NULL);
dispatch_queue_t main_queue = dispatch_get_main_queue();
NSString *path=#"https://www.fingerfry.com/pharmgo/uploads/product_image/";
NSString *url=[path stringByAppendingString:[[_ResponseDic valueForKey:#"main_image"]objectAtIndex:indexPath.row]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachePath = [paths objectAtIndex:0];
NSString *dataPath = [cachePath stringByAppendingPathComponent:url];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ( [fileManager fileExistsAtPath:dataPath] )
{
UIImage *image = [UIImage imageWithContentsOfFile:dataPath];
[cell.imgView setImage:image];
}
else
{
[cell.imgView setImage:[UIImage imageNamed:#"images.png"]];
dispatch_async(image_queue, ^{
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *image = [UIImage imageWithData:imageData];
[UIImagePNGRepresentation(image) writeToFile:dataPath atomically:YES];
dispatch_async(main_queue, ^{
[cell.imgView setImage:image];
});
});
}
I have the same issue, i had put the above code in cellForRowAtIndexPath, its working normal scrolling, hope its helpful
First install the pod:
pod 'SDWebImage/WebP', '~>3.7' in pod file.
Then you have to import:
#import <SDWebImage/UIImageView+WebCache.h>
Write below code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CustomTableCell";
LabTestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}//cell.txtHeading.text=#"hello";
cell.txtHeading.text=[[_ResponseDic valueForKey:#"title"]objectAtIndex:indexPath.row];
cell.txtdescribtion.text=[[_ResponseDic valueForKey:#"description"]objectAtIndex:indexPath.row];
cell.txtPrice.text=[[_ResponseDic valueForKey:#"purchase_price"]objectAtIndex:indexPath.row];
cell.txtLabName.text=[[_ResponseDic valueForKey:#"brand"]objectAtIndex:indexPath.row];
[cell.image sd_setImageWithURL:[NSURL URLWithString:[obj valueForKey:IMAGE_KEY]] placeholderImage:nil options:SDWebImageRefreshCached completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
}];
return cell;
}
Reference link :
https://github.com/rs/SDWebImage
So this is my Code:
TableViewController.h
#interface TableViewController : UITableViewController
#property (nonatomic, strong) NSArray *blogPosts;
#end
TableViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *blogURL = [NSURL URLWithString:#"http://blog.teamtreehouse.com/api/get_recent_summary/"];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData
options:0 error:&error];
self.blogPosts = [dataDictionary objectForKey:#"posts"];
}
With this being displayed on the log
2014-04-15 20:21:48.884 BlogReader[772:60b] Cannot find executable for CFBundle 0xa181ef0 (not loaded)
I forgot to make sure that the Author and Title strings matched the same ones as the ones in the JSON
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *blogPost = [self.blogPosts objectAtIndex:indexPath.row];
// Extracting 'Title' and 'Author' from dictionary to display in cell
cell.textLabel.text = [blogPost valueForKey:#"title"];
cell.detailTextLabel.text = [blogPost valueForKey:#"author"];
return cell;
}
output in tableview should be in each row,i am getting whole response in one row, remaining rows are blank .so how to display each row with data from server in uitableview
i get o/p as below in tableview
aa,bbb,cc……
hi,hello,"",…
o/p should be as below
aa
hi
bbb
hello
cc
""
this is my response
[{"result":[{"request_id":1,"ticket_number":"P_101","email":"xx","user_id":4,"description":"fjdyhsrwgk","status":"initiated"},{"request_id":2,"ticket_number":"P_102","email":"yyy","user_id":4,"description":"hi","status":"initiated"},{"request_id":3,"ticket_number":"P_103","email":"aaa","user_id":4,"description":"hii","status":"initiated"},{"request_id":4,"ticket_number":"P_104","email":"bbb","user_id":4,"description":"aa..","status":"initiated"}]}]
how to get array of objects in result key
below is code
listOfCustomers = [[NSMutableArray alloc]init];
str= [[NSUserDefaults standardUserDefaults] valueForKey:#"user_id"];
NSString *strJson=[NSString stringWithFormat:#"userId=%#",str];
NSString *strlength=[NSString stringWithFormat:#"%d",[strJson length]];
NSURL *url=[NSURL URLWithString:#"url"];
NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:url];
[request addValue:#"text/html" forHTTPHeaderField:#"Content-Type"];
[request addValue:strlength forHTTPHeaderField:#"Content-Length"];
NSData *requestData=[strJson dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:requestData];
[request setHTTPMethod:#"POST"];
NSError *err;
NSData *responseData=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&err];
NSString *strResponse=[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"response is %#",strResponse);
dict1=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&err];
NSArray *results = [dict1 valueForKey:#"result"];
listOfCustomers = [NSMutableArray array];
for (NSDictionary * oneCustomer in results)
{
// Create a new Customer record
Attributes * newCustomer = [[Attributes alloc] init];
newCustomer.Customer_ID = [oneCustomer valueForKey:#"request_id"];
newCustomer.Company_Name = [oneCustomer valueForKey:#"ticket_number"];
newCustomer.City = [oneCustomer valueForKey:#"email"];
newCustomer.userId = [oneCustomer valueForKey:#"user_id"];
newCustomer.description = [oneCustomer valueForKey:#"description"];
newCustomer.createdTime = [oneCustomer valueForKey:#"createdTime"];
newCustomer.Status = [oneCustomer valueForKey:#"status"];
// Add our new Customer record to our NSMutableArray
[listOfCustomers addObject:newCustomer];
}
[tableVwTotalRequests reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [listOfCustomers count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier=#"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"identifier"];
}
Attributes* cust = [listOfCustomers objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#",cust.Company_Name];
cell.detailTextLabel.text= [NSString stringWithFormat:#"%#",cust.description];
return cell;
}
Try this,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier=#"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"identifier"];
}
Attributes* cust = [listOfCustomers objectAtIndex:indexPath.row];
NSString *companyName = [NSString stringWithFormat:#"%#",cust.Company_Name];
NSArray *companyNames = [companyName componentsSeparatedByString:#","];
cell.textLabel.text = [companyNames objectAtIndex:indexPath.row];
NSString *description = [NSString stringWithFormat:#"%#",cust.description];
NSArray *descriptions = [description componentsSeparatedByString:#","];
cell.detailTextLabel.text= [descriptions objectAtIndex:indexPath.row];
}
You are defining your identifier as #"cell", but in your cell initialiser you are passing in the reuse identifier of #"identifier". These should be the same, pass in the variable instead, not the name of the variable as a string.
You are also missing out returning your cell at the end of the method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier=#"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
Attributes* cust = [listOfCustomers objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#",cust.Company_Name];
cell.detailTextLabel.text= [NSString stringWithFormat:#"%#",cust.description];
return cell;
}