I have a problem when I setImageWithURL on an UIImageView into an UITableViewCell.
Here is the table view rendered. On the left before that I pressed on the UITableViewCell and on the right after that I pressed it.
Here is my tableView:cellForRowAtIndexPath method :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"AddFriendCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary *user = self.result[indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", user[#"firstname"], user[#"lastname"]];
if (user[#"picture"]) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://jawbone.com/%#", user[#"picture"]]];
[cell.imageView setImageWithURL:url placeholderImage:cell.imageView.image];
}
return cell;
}
I just had a very similar problem last night. It happens because the UITableViewCell overrides the constraints on an imageview property, and for some reason has some unreliable functionality. I understand that this isn't exactly the most clear explanation as I did not ultimately figure out the exact source of the problem, but I was able to find a workaround.
The fix for me was to:
Create a custom UITableViewCell
Add a UIImageView (call the property something other than imageView) and title UILabel
Constrain/set the frame of the UIImageView
Related
I want to update button images in my table view. When my table view initially loads, the button images are correct. But when I scroll down the new cells don't update to my new images; they simply reuse a random old image from the initial set. I have tried setImage and setBackgroundImage. Here is my cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
SSKGrooveCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"grooveCell" forIndexPath:indexPath];
SSKSongCellInfo *entry = [_objects objectAtIndex:indexPath.row];
NSArray *icons = [plistHelper iconsForGroove:entry.metadata.title];
NSString *icon = [icons objectAtIndex:0];
NSString *iconImgString = [NSString stringWithFormat:#"element_%#_grooves", icon];
NSString *iconImgWithExt = [NSString stringWithFormat:#"%#.png", iconImgString];
[cell.inst1Button setBackgroundImage:[UIImage imageNamed:iconImgWithExt] forState:UIControlStateNormal];
cell.titleLabel.text = entry.metadata.title;
return cell;
}
return nil;
}
For a quick test, add this line in your cellForRowAtIndexPath
cell.imageView.image = [UIImage imageNamed:iconImgWithExt];
Do you see correct images?
If no, check your images and image names
If yes, check your inst1Button IBOutlet connection.
I just came across this issue on an app. Turns out there's a bug in iOS 7.1 regarding a UIButton in a UITableView. You need to call setNeedsLayout on the button after you've set the image. E.g.:
[cell.inst1Button setNeedsLayout];
I am facing a weird issue and I am sure I am doing something wrong. In my UITableViewController class I have a function as follows:
-(void)EERefreshView
{
NSLog(#"App delegate requested the view be refreshed");
[self loadEventsFromDB];
for(int a=0;a<eventsList.count;a++)
{
DB_EEEvent *event = (DB_EEEvent*)eventsList[a];
UITableViewCell *cell =
[self.tableView dequeueReusableCellWithIdentifier:#"Cell"];
//NSLog(#"CellID %#", cell.reuseIdentifier);
//get references to the UI components
UILabel *lblTitle = (UILabel*)[cell.contentView viewWithTag:5];
UILabel *lblDate = (UILabel*) [cell.contentView viewWithTag:6];
UIImageView *imgEvent = (UIImageView*)[cell.contentView viewWithTag:7];
//set values
lblTitle.text = event.name;
lblDate.text = [NSString stringWithFormat:#"%# - %#",
event.startdate,event.enddate];
AppDelegate *del = [AppDelegate sharedAppDelegate]; //need this to get the BaseURL
// Here we use the new provided setImageWithURL: method to load the web image
NSString * imageURL =[[NSString alloc] initWithFormat:#"http://%#%#",del.api.BaseURL,event.logo];
NSString* webStringURL = [imageURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:webStringURL];
[imgEvent setImageWithURL:url placeholderImage:[UIImage imageNamed:#"placeholder.png"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
//do somethign when image call completes
}];
[eventsListCells addObject:cell];
if(a == selectedEvent)
{
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[tblEventsList reloadData];
});
}
This function loads an array with UITableViewCell objects which is then used later on by
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Configure the cell data
NSLog(#"IndexPathRow: %d", indexPath.row);
UITableViewCell *cell = (UITableViewCell*)eventsListCells[indexPath.row];
return cell;
}
However when the cell is loaded lblTitle and lblDate have no text displaying in them. But when I tap on a cell it then displays the text in the labels. So this means that the data is there but its not being refresh when initially created. I suspect this might have something to do with threads but I am not an expert on the subject and would appreciate any help that I can get.
I see what is bothering you and why you created this method, but you don't need it. The only reason why you need back thread is your image loading so that should be thrown in bkg. thread and the rest of the code should be in -
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath.
U really don't need to pre create cells, and U cant cause they are reusable. For example if you have 50 elements in eventsList and room for only 5 cell on your screen you cant create 50 cells cause the code will create only 5+1 and reuse them as they appear on the screen, so every element of your eventsList will use one of those 5 cells and on the other side every cell will be a host for 10 different elements from your eventsList array. So as you can see your code doesn't make much sense...
The second function you mentioned in your question is the function that is called to populate the table with data. When you call [tblEventsList reloadData]; your app just calls the (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath method. So this method needs to be outputting data back to the table. A very simple example is below. Also, make sure your table delegate and data source are set.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Configure the cell.
cell.textLabel.text = [self.your_data_source objectAtIndex:[indexPath row]];
return cell;
}
I've added a UIImage to my table view cell. However, the UIImage is pushing the separator over to the right to make room for the UIImage. I'd like to find a way to have the separator include the UIImage and not be pushed over. Here is a picture of my table view cell.
Here is my cellForRowAtIndexPath method with code for the image:
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
Exercise *tempPlaceholder = [exercisesInTable objectAtIndex:indexPath.row];
NSString *exerciseDisplayName = tempPlaceholder.exerciseName;
exerciseDisplayName = [exerciseDisplayName capitalizedString];
exerciseDisplayName =
[exerciseDisplayName stringByReplacingOccurrencesOfString:#"_"
withString:#" "];
cell.textLabel.text = exerciseDisplayName;
cell.imageView.image = [UIImage imageNamed:#"quads.png"];
return cell;
}
If anyone could help me with this I'd really appreciate it. Thank you.
For anyone else who runs into this problem, using:
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
will fill the gap between the UIImage and the table cell separator.
Try change the size of imageView frame
cell.imageView.frame = CGRectMake(0, 0, 10.0, 10.0);
Or change the height of cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 40.0;
}
The behaviour you are experiencing will only occur on iOS 7 where the separators have insets that by default change with image view size.
To remove this behaviour simply set the separator insets to zero. However the separatorInset property is available on UITableView from iOS 7.0
So you only have to remove the inset in iOS 7.
You can check whether the table view responds to setSeparatorInset: doing
if ([self.tableview respondsToSelector:#selector(setSeparatorInset:)])
{
[self.tableview setSeparatorInset:UIEdgeInsetsZero];
}
I'm having a problem with loading images from my webserver into my UIImageView in a tableview
This code works perfect, but the images are placed weird and ugly in my tableview:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get the cell. Note that this name is the same as in the storyboard
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//Set the correct name in the cell.
//Do so by looking up the row in indexpath and choosing the same element in the array
NSInteger currentRow = indexPath.row;
Image* currentImage = [self.images objectAtIndex:currentRow];
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:currentImage.src] placeholderImage:[UIImage imageNamed:#"testimage.jpg"]];
return cell;
}
So I created an UIImageView on my storyboard, and changed the code to this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get the cell. Note that this name is the same as in the storyboard
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
//Set the correct name in the cell.
//Do so by looking up the row in indexpath and choosing the same element in the array
NSInteger currentRow = indexPath.row;
Image* currentImage = [self.images objectAtIndex:currentRow];
UIImageView *imgView = (UIImageView *)[cell viewWithTag:100];
// Here we use the new provided setImageWithURL: method to load the web image
[imgView setImageWithURL:[NSURL URLWithString:currentImage.src] placeholderImage:[UIImage imageNamed:#"testimage.jpg"]];
return cell;
}
But if I run this code on my device, I'm getting a signal SIGABRT error.
How can I get this working on my custom Imageview?
In the first code snippet, add these lines:
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
cell.imageView.clipsToBounds = YES;
You are getting SIGABRT because your imagevIview is NOT added to cell, but cell's contentView..! So the right way to get the imageView should be,
UIImageView *imgView = (UIImageView *)[cell.contentView viewWithTag:100];
I'm trying to display a UITableView with a list of artists who read from Last.fm API. I store all the artists in an array, then I show a table with your name and your picture.
Initially the photos look good, but when I do scroll the images are very small.
This is the initial appearance:
This is the appearance after scrolling, with the problem:
This is my code for create the cells:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TopArtistCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
JSCArtist *artist = self.artists[indexPath.row];
cell.textLabel.text = [artist name];
[cell.imageView setImageWithURL:[NSURL URLWithString:[[artist photo] thumbnail]] placeholderImage: [UIImage imageNamed:#"default_photo.jpeg"]];
return cell;
}
The default imageView for a UITableView acts a little odd. I would just create a custom UITableViewCell subclass and do your own layout.