Can't display an imageView from parse in tableview cell - ios

When the iOS app runs nothing shows up in the cells, the image is of type "file" in parse. I don't use the storyboard for this so I cant change the class for the imageView to PFImageView. What's missing?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// Configure the cell
PFFile *thumbnail = [object objectForKey:#"logo"];
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"placeholder.png"];
thumbnailImageView.file = thumbnail;
[thumbnailImageView loadInBackground];
cell.textLabel.text = [object objectForKey:#"name"];
cell.detailTextLabel.textColor=[UIColor lightGrayColor];
cell.backgroundColor = [UIColor clearColor];
thumbnailImageView=[[PFImageView alloc] initWithFrame:CGRectMake(9, 9, 30, 30)];
[thumbnailImageView setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:thumbnailImageView];
return cell;
}
Thanks in advance!

Do you actually need these 3 lines...
thumbnailImageView=[[PFImageView alloc] initWithFrame:CGRectMake(9, 9, 30, 30)];
[thumbnailImageView setBackgroundColor:[UIColor clearColor]];
[cell.contentView addSubview:thumbnailImageView];
You are already casting your existing ImageView to a PFImageView...
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
Which in turn should be the image view in you table cell. Does loadInBakground work well with table cells though? You could hit issues where the row its getting the image for may have already been reused by another image

I think the reason you can't see the image is because you are loading it in the background and setting it before the data has been obtained from parse. Could you try something like this:
// Set placeholder to show before image finishes loading
PFImageView *thumbnailImageView = (PFImageView*)[cell viewWithTag:100];
thumbnailImageView.image = [UIImage imageNamed:#"placeholder.png"];
PFFile *thumbnail = [object objectForKey:#"logo"];
[thumbnailImageView setFile:thumbnail];
[thumbnailImageView loadInBackground:^(UIImage *image, NSError *error) {
if (!error) {
// Configure your image view in here
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(9, 9, 30, 30)];
[imageView setBackgroundColor:[UIColor clearColor]];
[imageView setImage:image];
[cell.contentView addSubview:imageView];
}
}];
Try something along these lines.

Related

Replacing button images shows weird issue

I have two images I used for showing on/off. Everything was working perfectly. When my designer asked to replace the images, I replaced the images and replaced the name of the images in the class. Suddenly the switching isn't happening any more. I used [button setImage:image forState:UIControlStateNormal]; With condition. My condition is working perfectly. But image never changes. Replacing these images with the old images worked perfectly for the same code.
Now, I again replaced it back it to the new images and added setBackgroundColor for Button. Strangely the images are getting replaced. If I take away the backgroundColor method it doesn't work. Does anyone knows why this happens?? I think the image is getting set as background image as well. But I haven't used a single code anywhere to set the background image.
Update
This is the place I set the images. Where in viewDidLoad
selectedImage = [UIImage imageNamed:kcheckSelected];
notSelectedImage = [UIImage imageNamed:kcheckUnselect];
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"cellIdentifier";
UITableViewCell *cell = [tableview dequeueReusableCellWithIdentifier:identifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(15, 0, tableview.frame.size.width - 15, 1)];
view.backgroundColor = [UIColor lightGrayColor];
[cell.contentView addSubview:view];
}
NSString *sltd= [selectionArray objectAtIndex:indexPath.row];
UIImage *image = nil;
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(tableview.frame.size.width - 60, 5, 60, 50)];
if ([sltd isEqualToString:#"yes"])
{
image = selectedImage;
}
else
{
image = notSelectedImage;
}
[button setBackgroundColor:[UIColor whiteColor]];
button.tag = indexPath.row;
[button addTarget:self action:#selector(selectButton:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:image forState:UIControlStateNormal];
[cell.contentView addSubview:button];
[cell.contentView bringSubviewToFront:button];
User *userObj = [userArray objectAtIndex:indexPath.row];
cell.textLabel.text = userObj.name;
cell.textLabel.font = [UIFont fontWithName:#"Montserrat-Regular" size:17];
if ([userObj.installOnIpad boolValue] == YES)
{
cell.imageView.image = [UIImage imageNamed:#"ipad-icon-active"];
}
else
{
cell.imageView.image = [UIImage imageNamed:#"ipad-icon-disabled"];
}
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}

Loading many records in UITableView

I am loading a UITableView in this way:
- (UITableViewCell *)tableView:(UITableView *)tableViewLocal cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
CustomTableViewCell *cell = [tableViewLocal dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
for(UIView *subview in cell.contentView.subviews)
{
[subview removeFromSuperview];
}
UIImage* img;
UIImageView *imv = [[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 60, 60)];
if(isFiltered == TRUE){
cell.textLabel.text = [filteredTableData objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:14];
}
if(isFiltered == FALSE){
cell.textLabel.text = [itemArray objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.detailTextLabel.text = [NSString stringWithFormat:#"date added: %#", [DKStoreManager dateFileWasCreatedWithFileName:[itemArray objectAtIndex:indexPath.row] inFolderNumber:[_FolderCode intValue] forUser:[_PassedUserID intValue] andType:_FolderType]];
}
NSData* data = [DKStoreManager loadFileWithName:[itemArray objectAtIndex:indexPath.row] forFolderNumber:[_FolderCode intValue] forUser:userID andType:_FolderType];
img = [[UIImage imageWithData:data] cropToSize:CGSizeMake(320, 320) usingMode:NYXCropModeCenter];
imv.image = img;
[cell.contentView addSubview:imv];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
As you can see I have an itemArray with all the names of the files, and for each cell I load the relative NSData in this way:
NSData* data = [DKStoreManager loadFileWithName:[itemArray objectAtIndex:indexPath.row] forFolderNumber:[_FolderCode intValue] forUser:userID andType:_FolderType];
Since it also loads images (and there may be more than 300 cells), the UI frees.
I have tried loading only the visible cells using the accepted answer of this link:
tableView: cellForRowAtIndexPath: get called not only for visible cells?
however all of the cells are loaded at the same time. I have no idea of how to do this...
cellForRowAtIndexPath gets called when the tableView reloads as well as when the user scrolls. The UI freeze could be due to the fact that your calling
for(UIView *subview in cell.contentView.subviews)
{
[subview removeFromSuperview];
}
UIImageView *imv = [[UIImageView alloc]initWithFrame:CGRectMake(5, 5, 60, 60)];
which means that every time the user scrolls , you are iterating through all the subViews and removing them, as well as allocating UIimageView's at the same time, this is not a good way to go about displaying content. You can use the tableViewCell's default imageView property to display your image. After getting you image just say
cell.imageView.image = img;

Adding one image to specific UICell using if statement adds it to multiple UICells Objective-c

I'm using an if statement so that only specific cells gets images. In my test examples there is only one cell that should get an image and the if statement gets run only once. The if statement also changes the text of the labels. The labels are correctly changed but the image is added to multiple cells especially when I scroll up and down. How to I get it to not add extra images to other cells.
UIImageView *imageView= [[UIImageView alloc]initWithFrame:CGRectMake(114,5, 122, 63)];
if (condition) {
[imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"Placeholder.png"]];
imageView.tag = 777;
[cell addSubview:imageView];
cell.titleLabel.text = [dict valueForKey:#"name"];
cell.titleDescription.text = [dict valueForKey:#"summary"];
} else {
[[cell viewWithTag:777] removeFromSuperview];
}
The UITableViewCell is cached, so instead of always creating a new UIImageView, check first if it has one:
UIImageView * imageView = (UIImageView*)[cell viewWithTag:777];
if (condition) {
if(!imageView) {
imageView= [[UIImageView alloc]initWithFrame:CGRectMake(114,5, 122, 63)];
}
[imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"Placeholder.png"]];
imageView.tag = 777;
[cell addSubview:imageView];
cell.titleLabel.text = [dict valueForKey:#"name"];
cell.titleDescription.text = [dict valueForKey:#"summary"];
} else {
[imageView removeFromSuperview];
}
You were likely adding multiple imageViews to one cell, so removeFromSuperView was only removing the first one.
Do like this
during the creation of cell that is
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [aTableVIew dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"]autorelease];
UIImageView *aImgView = [[UIImageView alloc]initWithFrame:CGRectMake(20, 0, 40, 40)];
aImgView.tag = 777;
[cell addSubview:aImgView];
[aImgView release];
}
//use your condition hear onwards to make changes
if(indexPath.section == 0)
{
UIImageView *view = (UIImageView *)[cell viewWithTag:777];
view.image = [UIImage imageNamed:#"peter.png"];
}
else if (indexPath.section == 1)
{
if(indexPath.row == 0 )
{
UIImageView *view = (UIImageView *)[cell viewWithTag:777];
view.image = nil;
}
else
{
UIImageView *view = (UIImageView *)[cell viewWithTag:777];
view.image = [UIImage imageNamed:#"peter.png"];
}
}
return cell;
}
change according to requirement
note: i am not using ARC

Custom imageview in tableview cell

What is wrong with this code? The image is not displayed. Appreciate any help...
Stepping through the code, I can see that all the variables are updated correctly. The code executes without any errors. The image is not seen though.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ModuleViewCellId = #"ModuleViewCellId";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ModuleViewCellId];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ModuleViewCellId] autorelease];
}
NSUInteger row = [indexPath row];
NSDictionary *step = [self.module.steps objectAtIndex:row];
cell.textLabel.text = [step objectForKey:kStepTitleKey];//;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:14.0];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.backgroundColor = [UIColor clearColor];
cell.indentationWidth = 50;
cell.indentationLevel = 1;
//2/6 shp - add icons to the table view
NSString *imagename = [step objectForKey:kStepIconKey];
NSLog(#"%#",imagename);
UIImageView *image;
image = [[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 57, 57)] autorelease];
image.tag = 1000 + row;
image.contentMode = UIViewContentModeScaleAspectFit;
image.hidden = FALSE;
[image setImage: [UIImage imageNamed:imagename]];
[cell.contentView addSubview:image];
return cell;
}
I just found the answer. The problem was with the path to the file names. All my image files are stored in a bundle. So even though the image file names are correctly referenced, the path needed to be appended.
Adding the path this way fixed the problem.
NSString *imagename = [NSString stringWithFormat: #"%#%#", #"Assets.bundle/assets_dir/",[step objectForKey:kStepIconKey]];
This answer also helped me. UITableViewCell with images in different dimensions
Since you are using default cell i.e uitableViewCell, make use of imageview property of the cell.
UITableViewCell *cell =[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.imageView.image = [UIImage imageNamed:#"ImageName"];
cell.imageView.contentMode = UIViewContentModeScaleAspectFit;

How to load images asynchronously in uitableview without memory warning?

Hi iam developing an app where i will fetch images from web service and load the images in tableview. I loaded the images asynchronously. The problem is my app get crash while scrolling the tableview and in log it shows memory recieved warning.Also same images gets repeated in many rows.Also it takes more time to load. i used the below code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
/* UILabel * cellLabel=[[UILabel alloc] initWithFrame:CGRectMake(0, 50, cell.frame.size.width-20, 45)];
cellLabel.textColor=[UIColor blackColor];
cellLabel.backgroundColor=[UIColor clearColor];
cellLabel.tag=2;
[cell.contentView addSubview:cellLabel];*/
cell.selectionStyle=UITableViewCellSelectionStyleNone;
cell.backgroundView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"list_iPhone.png"]];
UIImageView *imv = [[UIImageView alloc]initWithFrame:CGRectMake(10,18, 48, 48)];
imv.tag=4;
imv.image=[UIImage imageNamed:#"ImagePlaceholder.png"];
[cell.contentView addSubview:imv];
UIImageView *arrwimv = [[UIImageView alloc]initWithFrame:CGRectMake(260,35, 14, 17)];
arrwimv.image=[UIImage imageNamed:#"arrw_iPhone.png"];
[cell.contentView addSubview:arrwimv];
UILabel *descriptionLbl=[[UILabel alloc] initWithFrame:CGRectMake(100, 27, 450, 45)];
descriptionLbl.font=[UIFont CITY311_TitleFontWithSize:18];
descriptionLbl.tag=1;
descriptionLbl.textAlignment=UITextAlignmentLeft;
descriptionLbl.textColor=[UIColor blackColor];
descriptionLbl.backgroundColor=[UIColor clearColor];
[cell.contentView addSubview:descriptionLbl];
UILabel *descriptionLbl2=[[UILabel alloc] initWithFrame:CGRectMake(100, 5, 450, 45)];
descriptionLbl2.font=[UIFont CITY311_TitleFontWithSize:18];
descriptionLbl2.tag=2;
descriptionLbl2.textAlignment=UITextAlignmentLeft;
descriptionLbl2.textColor=[UIColor blackColor];
descriptionLbl2.backgroundColor=[UIColor clearColor];
[cell.contentView addSubview:descriptionLbl2];
}
UIImageView *imv2=(UIImageView *)[cell.contentView viewWithTag:4];
dispatch_async(mainQueue, ^(void) {
if(![[[issueArray objectAtIndex:indexPath.row]objectForKey:#"PhotoUrl"] isEqualToString:#""])
{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[[issueArray objectAtIndex:indexPath.row]objectForKey:#"PhotoUrl"]]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
imv2.image = image;
}
});
UILabel *lbl=(UILabel *)[cell.contentView viewWithTag:1];
lbl.text=[[issueArray objectAtIndex:indexPath.row] objectForKey:#"issueSubmittedDate"];
UILabel *lbl2=(UILabel *)[cell.contentView viewWithTag:2];
lbl2.text=[[issueArray objectAtIndex:indexPath.row] objectForKey:#"IssueName"];
return cell;
}
In view did load
mainQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
In .h file
dispatch_queue_t mainQueue;
Please help to load the images properly without any memory warning(Crash).Thanks in Advance.
you are reusing tableviewcells. When a cell moves off the screen, it will be set aside so that you can reuse the object. When you are doing a dequeueReusableCellWithIdentifier you can get a 'old' cell that already contains an image. If you dont' clear the data from that cell you will see the old data (image) until the new image is downloaded.
inside the if(cell==nil) you should only create the cell and set properties that will be the same for every row. Set and clear the data below that if.
The crashes probably happen because a cell can be moved out of the view and reused for an other row before the initial callback is ready. Try setting the identifier to a unique value. Something like:
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d", indexPath.Row];
Only keep your code like that when the number of rows is low. Otherwise you could get memory problems.
Instead of trying to fix it yourself, you could try using something like https://github.com/rs/SDWebImage

Resources