I have the following behavior: i have a table with number of rows = 20
i have created in Storyboard UITableView Cell with UIImage.
I use the function didSelectRowAtIndexPath for show and hide a image. If i select a row the UIImage xxx.png will be displayed. If i select the same row again then the Image is hidden. That works perfekt but when i scroll down i see rows with images and i have no selected this rows.
I will only see the image when i select a row and not duplicates wehen i scroll the table.
Here is my code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
WorkoutTableVCell *cell = [tableView dequeueReusableCellWithIdentifier:#"WorkoutCell" forIndexPath:indexPath];
cell.checkImage= nil;
if (cell == nil)
{
cell = [[WorkoutTableVCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"WorkoutCell"];
}
else{
//Old cell...get previously createdd imageview
cell.checkImage = (UIImageView*)[cell.contentView viewWithTag:1001];
}
long row = [indexPath row];
cell.lblCell.text = _MyValues[row];
return cell;
}
I hope you can understand my problem and sorry for my bad english :(
Cells are reused, so you need set the image of the cell each time. You need to have another data source that contains images for each indexPath and use that to set the image for the UIImageView in the cell.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
WorkoutTableVCell *cell = [tableView dequeueReusableCellWithIdentifier:#"WorkoutCell" forIndexPath:indexPath];
if (cell == nil)
{
cell = [[WorkoutTableVCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"WorkoutCell"];
}
long row = [indexPath row];
cell.lblCell.text = _MyValues[row];
// set the image for the UIImageView here
cell.imageView.image = _MyImages[row];
return cell;
}
An even better approach would be to have your data source be a key/value pair (like a NSDictionary) with the Keys being the text that goes in the label and the value being the image that should be assigned to the UIImageView.
Related
I have a TableViewController with Prototype Cells that look like this:
I would like to only display the Title and Date labels by default when the TableView data loads. Additionally, when the user selects a particular cell, I want the cell to expand so that the user can read the contents of the Description label (which can run over multiple lines).
I have looked through several sources on StackOverflow including the following: https://stackoverflow.com/a/3075493/4481169.
Most of the sources I have looked through assume that when the cell is not selected it will return to a specific height. However, the text of my Title label can take up multiple lines in some cases which means that each cell will have a different initial row height to begin with.
How can I make it so when the user selects a particular cell it expands to display all three labels and when that cell is unselected, the cell reverts to its original height?
Probably the easiest way to achieve this would be having 2 cell prototypes for:
Not selected: with 2 UILabels; // let is be with ID: #"NotSelectedCell"
Selected: with all 3 UILabels; // #"SelectedCell"
Also You need to store the indexPath of the selected cell, so:
#implementation InformationTableViewController {
NSIndexPath* selectedCellIndexPath;
}
In your tableView delegate method tableView:cellForRowAtIndexPath: you need to switch between NotSelectedCell and SelectedCell according to the indexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([indexPath isEqual:selectedCellIndexPath]) {
NSString* cellIdentifier = #"SelectedCell";
InformationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (cell == nil) {
cell = [[InformationTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.title = // title
cell.date = // date
cell.description = // description
return cell;
}
else {
NSString* cellIdentifier = #"NotSelectedCell";
InformationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier forIndexPath:indexPath];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (cell == nil) {
cell = [[InformationTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.title = // title
cell.date = // date
return cell;
}
}
Also you must save a new indexPath everytime user selects a new cell and reload the tableView:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedCellIndexPath = [indexPath copy];
[self.tableView reloadData];
}
In order to recover the scroll position of the tableView before reload, you have to do the following:
CGFloat tableViewContentHeight = self.tableView.contentSize.height;
[self.tableView reloadData];
CGFloat newTableViewContentHeight = self.tableView.contentSize.height;
self.tableView.contentOffset = CGPointMake(0, newTableViewContentHeight - tableViewContentHeight);
For your requirement i would suggest you to do this steps
First of don't give height constraint to description and even don't
add any text in it i.e keep it blank
Then when you get the values for description store in other array
After this on delegate method for didselectrowatindex you can fill
the value of that description and it reload it .
So it will fill the text in description and take the height as
required
I have following code :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *tableId = #"details";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableId];
if(cell == nil)
{
cell = [ [UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:tableId];
}
[((UIImageView *)[cell viewWithTag:101]) setImage:[UIImage imageNamed:[homeInvCaptureViewModel.productArray objectAtIndex:indexPath.row]]];
return cell;
}
I have a table view in storyboard. Yet, my data is not shown up in my table rows. (i.e., imageview).
I just try your code, and it's working for me, so I see some explanations for your bug:
Did you set 101 for your ImageView's tag in your storyboard?
Did you set details as cell's identifier is in your storyboard?
Are you sure your image's name from your productArray exists in your project's images?
You should set an image at your ImageView in your storyboard to identify,
Now I have a dynamic cell to show lists. And Using Search Bar and Search Display Controller. Why it shows blank on simulator.
Before filtering,the simulator shows all cells and disclosure could link to another table view. After filtering, it should show some of cells. But it is blank. And the disclosure is not worked as well.
Codes for cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"MovieCell";
MovieCell *cell = (MovieCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Movie *movie = nil;
if (cell == nil) {
cell = [[MovieCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView) {
movie= [filteredMovieArray objectAtIndex:[indexPath row]];
} else {
movieArray = self.movies;
movie = [movieArray objectAtIndex:[indexPath row]];
}
cell.nameLabel.text = movie.movieName;
cell.placeLabel.text = movie.place;
cell.categoryLabel.text = movie.category;
cell.isFavLabel.text = movie.isFavourite ? #"Favourite" : #"Not Favourite";
[cell.starRating setRating:movie.rating];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
NSLog(#"description = %#",[cell description]);
return cell;
}
I made it. I think this is a good answer for it: Search Bar in UITableView doesn't display text in Cell label.
What's more, I also add this code section to fit the cell height:
- (void)searchDisplayController:(UISearchDisplayController *)controller didLoadSearchResultsTableView:(UITableView *)tableView {
tableView.rowHeight = 87;
}
This number is the row height of my cell.
I have a text array backing a TableView in iOS. In the cellForRowAtIndexPath: method I return a UITableViewCell* which is populated with text from the backing array. indexPath is used as the index into the backing array.
I now want to add a "Done" button to the last cell in the TableView. In my StoryBoard I've created a second (prototype) TableView Cell and gave it the identifier "ButtonCell". I've also added an extra element to the end of the backing array so numberOfRowsInSection: can return the count of the backing array and everything will just work.
I thought I would set the text of the last array element to something like #"donebutton" and then I could check for that in cellForRowAtIndexPath:. If it comes up true, I would know I'm at the end of my array and to return the "ButtonCell" cell instead of the normal "Cell". Thing is, it's not quite working right. What's the best way to accomplish this? Code snip is below.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
static NSString *ButtonCellIdentifier = #"ButtonCell";
UITableViewCell *bcell = [tableView dequeueReusableCellWithIdentifier:ButtonCellIdentifier forIndexPath:indexPath];
NSString *rowtext = [_mArCellData objectAtIndex:indexPath.row];
// return button cell if last item in list
if ([rowtext isEqualToString:[NSString stringWithFormat:#"%d", SUBMIT_BUTTON]])
{
NSLog(#"hit last row, so using button row");
return bcell;
}
cell.textLabel.text = rowtext;
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
static NSString *ButtonCellIdentifier = #"ButtonCell";
UITableViewCell *cell;
if (indexPath.row != ([_mArCellData count] - 1) { // if not the last row
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// configure cell...
} else { // last row
cell = [tableView dequeueReusableCellWithIdentifier:ButtonCell];
// configure button cell...
}
return cell;
}
I would just change your if statement to:
if ([tableView numberOfRowsInSection:0] == indexPath.row + 1) {
NSLog(#"hit last row, so using button row");
bcell.textLabel.text = rowtext;
return bcell;
}
This is a little more abstracted than your solution and doesn't rely on a property of a cell being set to anything in particular. I like the way #bilobatum put the dequeueReusableCellWithIdentifier: call in the if statement. That should save some memory as well.
EDIT: I also noticed that you are setting cell text, but not bcell text.
In iOS, I basically want to display images as follows:
I need 2 columns in a table. The image in the first column is fixed, and in the second column the rows should have horizontal scrolling to scroll the images. On selecting an image it should go to another view.
You need to follow this tutorial, and the likes of it.
For details about how to have fixed first image, there is no better way than starting from scratch, going by the books.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if(indexPath.row == 0){
//Normar cell
}else if(indexPath.row == 1){
//add ScrollVeiw
}
}
and for the height of the cell
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.row == 1) {
//height for scrollview
}
}