Hi I am trying the code bellow and I can't get my image showing
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *CellIdentifier = #"Cell";
PFTableViewCell *cell = (PFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[PFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell
cell.textLabel.text = [object objectForKey:#"venueName"];
cell.imageView.file = [object objectForKey:#"image"];
[cell.imageView.file getDataInBackgroundWithBlock:^(NSData *data, NSError *error){
cell.imageView.image = [UIImage imageWithData:data];
}];
return cell;
}
I also try:
[cell.imageView loadInBackground];
and nothing. Do I need to insert manually an UIImage in the cell?
Regards
To load a image from Parse.com (using PFImageView), you just do it:
creature.file = (PFFile *)file;
[creature loadInBackground];
Are you sure that the property "image" is a file? If it is, try this:
PFFile *theImage = [object objectForKey:#"image"];
[theImage getDataInBackgroundWithBlock:^(NSData *data, NSError *error){
NSData *imageFile = [theImage getData];
cell.imageView.image = [UIImage imageWithData:imageFile];
}];
Related
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
(void)bilgileriYukle
{
NSMutableArray *yemekIsimleri = [[NSMutableArray alloc] init];
NSMutableArray *resimIsimleri = [[NSMutableArray alloc] init];
NSURL *myURL = [[NSURL alloc]initWithString:#"http://www.sevgilezzeti.com/WebServices/tarifler.php"];
NSData *myData = [[NSData alloc]initWithContentsOfURL:myURL];
if (myData == nil)
{
NSLog(#"INTERNET YOK YADA VERI CEKEMEDI");
}
else
{
NSLog(#"INTERNET VAR VERI CEKILDI");
NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:myData options:kNilOptions error:nil];
for (id element in jsonArray)
{
NSString *durum = [element objectForKey:#"durum"];
if([durum isEqualToString:#"1"])
{
[yemekIsimleri addObject:[element objectForKey:#"yemekadi"]];
NSString *gelenYemekAdi =[element objectForKey:#"kapakresmi"];
NSString *imagePathKapak = #"http://sevgilezzeti.com/Admin/yemekresimkapak/";
combined = [NSString stringWithFormat:#"%#%#", imagePathKapak, gelenYemekAdi];
[resimIsimleri addObject:combined];
}
}
}
_TarifAdi=yemekIsimleri;
_ResimAdi=resimIsimleri;
}
///////////////////////////////////////////////////////////////////////////////////////
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell" forIndexPath:indexPath];
NSUInteger row = [indexPath row];
cell.TitleLabel.text = _TarifAdi[row];
NSCache *_imageCache;
UIImage *image = [_imageCache objectForKey:#"DenemeRes"];
if (image == nil) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_ResimAdi[row]]];
image = [UIImage imageWithData:data];
[_imageCache setObject:image forKey:#"DenemeRes"];
}
cell.ThumbImage.image = image;
return cell;
}
I can get images from URL and can see images but when I scroll the table view, it's very slow and lagging. How can I fix this problem ?
It's pretty easy and straightforward to load images synchronously in table view cells, however it's evil, because it would cause the lag when you scroll it, because it's actually trying to load and display the images as you're scrolling.
Therefore, you must avoid loading images synchronously, but asynchronously instead, using a different thread other than the main thread, so that the scrolling and loading + displaying images can be done dependently, avoiding any kind of lag.
This is possibly a duplicate question, since it's already been asked and there are tutorials out there, but since I myself always had a problem with this on my first iOS app and found it very confusing, I'm posting the answer here, hoping it's helpful.
Try adding something like this to your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:
// Get the filename to load.
NSString *imageFilename = [imageArray objectAtIndex:[indexPath row]];
NSString *imagePath = [imageFolder stringByAppendingPathComponent:imageFilename];
[[cell textLabel] setText:imageFilename];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
dispatch_sync(dispatch_get_main_queue(), ^{
[[cell imageView] setImage:image];
[cell setNeedsLayout];
});
});
dataWithContentsOfURL is blocking your main thread, that'w why the table is acting like it is. You should load images in back thread so that the main thread can handle UI without interruptions
NSURL *url = [NSURL URLWithString:link];
NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url cachePolicy:0 timeoutInterval:kTimeoutInterval];
[NSURLConnection sendAsynchronousRequest:urlRequest
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
UIImage *image = [[UIImage alloc] initWithData:self.activeDownload];
// set to ImageView
cell.ThumbImage.image = image;
}];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell" forIndexPath:indexPath];
cell.tag = indexPath.row;
cell.imageView.image = nil;
// Rounded Rect for cell image
CALayer *cellImageLayer = cell.imageView.layer;
[cellImageLayer setCornerRadius:35];
[cellImageLayer setMasksToBounds:YES];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^(void) {
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_ResimAdi[indexPath.row]]];
UIImage *image = [[UIImage alloc] initWithData:data];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
CGSize itemSize = CGSizeMake(70, 70);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[cell setNeedsLayout];
}
});
}
});
cell.TitleLabel.text = _TarifAdi[indexPath.row];
return cell;
}
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;
}
In a DetailView I am trying to show more than 1 image from Parse.com backend so I have this code:
EDIT:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"Cell";
VestimentaDetailCell *cell = (VestimentaDetailCell *) [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
static int index = 1;
PFFile *imageFile = [self.vestimenta objectForKey:[NSString stringWithFormat:#"image_%d", index ]];
[imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
cell.imageFile.image = [UIImage imageWithData:data];
}
}];
return cell;
}
It works.. The problem is that once the user has viewed the images once they no longer appear again.
So I tried just implementing:
PFFile *imageFile = [self.vestimenta objectForKey:[NSString stringWithFormat:#"image_%d"]];
But then I get the error of "More '%' conversions than data arguments.
How do I set the code?
Change
PFFile *imageFile = [self.vestimenta objectForKey:[NSString stringWithFormat:#"image_%d"]];
To
PFFile *imageFile = [self.vestimenta objectForKey:[NSString stringWithFormat:#"image_%#", index ]];
When u write something like NSLog(#" %d %f %#"), u should pass arguments like this :
NSLog(#"%d %f %#", someInt, someFloat, someString);
You can try this:
PFFile *imageFile = [self.vestimenta objectForKey:[NSString stringWithFormat:#"image_%d+1", indexPath.row ]];
Hope that help.
You need to provide an argument for the %d in the string format.
Perhaps you need this:
PFFile *imageFile = [self.vestimenta objectForKey:[NSString stringWithFormat:#"image_%d", index]];
With the help of all the answers in this questions I figured it out.
Here is the code for anyone who encounters the same problem:
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"Cell";
VestimentaDetailCell *cell = (VestimentaDetailCell *) [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
PFFile *imageFile = [self.vestimenta objectForKey:[NSString stringWithFormat:#"image_%d", indexPath.row]];
[imageFile getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
if (!error) {
cell.imageFile.image = [UIImage imageWithData:data];
}
}];
return cell;
}
So i have problem...For me, Having the dispatch_async code within cellForRowAtIndexPath method is too clunky and messy for me.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier = #"myCellID";
myCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// someData - an array of dictionary for the tableview datasource
NSURL * imageURL = [NSURL URLWithString:someData[indexPath.row][#"photoURL"]];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
cell.myImageView.image = image;
});
});
}
So after a little research my solution to this was:
-(void)loadAsyncImage:(NSIndexPath *)indexPath{
NSURL * imageURL = [NSURL URLWithString:someData[indexPath.row][#"photoURL"] ];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
UIImage *myImage = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
// _myTableView a property link from the interface builder
myCell * cell = (id)[_myTableView cellForRowAtIndexPath:indexPath];
cell.myImageView.image = myImage;
});
});
}
and then in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
static NSString *CellIdentifier = #"myCellID";
myCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[self loadAsyncImage: indexPath];
}
To my surprise it works and is so much more cleaner...but... i dont know if this is the right way to do this. Is there a better approach to this issue? or is this ok?