How to set image in selected cell row in UITableView [closed] - ios

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I want to know how to set image in Selected cell row in UITableView.
If I select the first cell, image should display in first cell and later when I select the second cell, image should display in second cell only (and not in first cell)
Basically, image should display in the selected cell only.

The cleanest approach would be to subclass UITableViewCell.
#import <UIKit/UIKit.h>
#interface SongCell : UITableViewCell
#property (nonatomic, assign) BOOL isPlaying;
#end
#interface SongCell ()
#property (nonatomic, strong) UIImage *speakerImage;
#end
#implementation SongCell
-(void)layoutSubviews
{
if (!_speakerImage) {
// http://commons.wikimedia.org/wiki/File:Speaker_Icon.svg
self.speakerImage = [UIImage imageNamed:#"speaker_icon.png"];
}
if(!self.isPlaying){
self.imageView.image = nil;
} else {
self.imageView.image = _speakerImage;
self.imageView.hidden =NO;
}
[super layoutSubviews];
}
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if (!selected) {
self.isPlaying = NO;
}
}
-(void)setIsPlaying:(BOOL)isPlaying
{
_isPlaying = isPlaying;
[self setNeedsLayout];
}
#end
The UITableViews datasource and delegate implementation
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"SongCell";
SongCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier forIndexPath:indexPath];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SongCell *cell =(SongCell *)[tableView cellForRowAtIndexPath:indexPath] ;
cell.isPlaying = !cell.isPlaying;
}
I prepared a demo project for you. You will find it on GitHub

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
[UIView animateWithDuration:2.0f animations:^{
[imageView setHidden:NO];
} completion:^(BOOL finished) {
;
}];
}

You want a toggling type nature for the imageView.
- (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];
}
[cell.imageView setImage: [UIImage imageNamed:#""]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//refresh all cells
//basically call cellForRowAtIndexPath to reset all cells
[tableView reloadSections:indexPath.section
withRowAnimation:UITableViewRowAnimationFade];
//get cell for the currently selected row
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//set image
[cell.imageView setImage: [UIImage imageNamed:#"loudspeaker.png"]];
}
But this is just a visual aspect.
If you select the first row and scroll down and later return to the first row, the image would no longer be there because -cellForRowAtIndexPath: is recalled and since we had [cell.imageView setImage: [UIImage imageNamed:#""]]; in it, the imageView.image is reset.
To handle the above scenario, you need to remember which rows were selected. (you can achieve this by a basic array)
Example:
- (void)viewDidLoad {
[super viewDidLoad];
//arrMyDataSource is defined in .h as 'NSArray *arrMyDataSource;'
//needless to say but this is the tableView's datasource contents
arrMyDataSource = #[#"Apple",#"Banana",#"Candy",#"Door",#"Elephant"];
//arrMemoryMap is defined in .h as 'NSMutableArray *arrMemoryMap;'
//this is one way to remember which row is selected
arrMemoryMap = [NSMutableArray alloc] init];
for (int i = 0 ; i < arrMyDataSource.count ; i++) {
NSNumber *tmpSelectStatus = [NSNumber numberWithBool:NO];
[arrMemoryMap addObject: tmpSelectStatus];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//...
if([[arrMemoryMap objectAtIndex:indexPath.row] boolValue] == YES) {
[cell.imageView setImage: [UIImage imageNamed:#"loudspeaker.png"]];
} else {
[cell.imageView setImage: [UIImage imageNamed:#""]];
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//first, reset arrMemoryMap for all rows
for (int i = 0 ; i < arrMemoryMap.count ; i++) {
if([[arrMemoryMap objectAtIndex:i] boolValue] == YES]) {
[[arrMemoryMap objectAtIndex:i] setBoolValue: NO];
break;
}
}
//now, set current row as selected in arrMemoryMap
[[arrMemoryMap objectAtIndex:indexPath.row] setBoolValue: YES];
//reload data or particular section
[tableView reloadSections:indexPath.section
withRowAnimation:UITableViewRowAnimationFade];
}

Related

How to get values of tableview cells having multiple selections?

I have a tableview in which i have provided checkmarks as a accessory to multiple cells.
Now I want to get values of all those cells having checkmarks.
#import "HealthIssues.h"
#interface HealthIssues ()<UITableViewDataSource,UITableViewDelegate>
{
NSIndexPath* checkedIndexPath;
}
#property (nonatomic, retain) NSIndexPath* checkedIndexPath;
#end
#implementation HealthIssues
#synthesize HealthIssuesTV;
#synthesize checkedIndexPath;
- (void)viewDidLoad {
[super viewDidLoad];
PickerList=[[NSArray alloc]initWithObjects:#"None" ,#"Diabetes", #"Heart Problem" , #"Thyroid" , #"Over Weight" , #"Kidney Issues" , #"Lever Issues" , #"Vitamins Deficiency" , #"Blood Pressure" , nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [PickerList count];
}
- (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];
}
if (indexPath.row == 0){
if ([self.checkedIndexPath isEqual:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
cell.textLabel.text = [PickerList objectAtIndex:indexPath.row];
cell.tintColor=[UIColor blueColor];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
{
int z=0;
if (indexPath.row==0)
{
NSArray *visibleCells = [tableView visibleCells];
for (UITableViewCell *cell in visibleCells)
{
if (z==0)
{
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
z++;
}
else
{
[cell setAccessoryType:UITableViewCellAccessoryNone];
z++;
}
}
}
else
{
if ([selectedCell accessoryType] == UITableViewCellAccessoryNone)
{
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
}
else
{
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
}
[tableView reloadData];
}
}
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#end
This Works perfect for me as per my requirements. now i want to store selected rows in dictionary.
#interface selectUsers ()
{
NSMutableArray *selected_ids;
}
- (void)viewDidLoad {
[super viewDidLoad];
selected_ids = [[NSMutableArray alloc]init];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *_id = [[yourarray objectAtIndex:indexPath.row]valueForKey:#"_id"];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
[selected_ids removeObject:_id];
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
[selected_ids addObject:_id];
cell.accessoryType=UITableViewCellAccessoryCheckmark;
}
}
Use selected_ids array where you want.
Try to get values from your data source of array and get all selected rows of UITableView:
Following code will give you all indexpaths of selected rows:
NSArray *arrIndexpaths = [YourTableView indexPathsForSelectedRows]; // Returns indexpaths for multiple selection in Table view.
Then Get value from the array by indexpath.row and indexpath.section whatever you used during in data source method.
First of all, you should do:
tableView.allowsMultipleSelection = YES;
Then you can get list of selected rows by:
NSArray *selectedIndexPaths = [self.tableView indexPathsForSelectedRows];
As you have now list of selected rows, you can get row or data of row.
You can use array for this.
- (void)viewDidLoad
{
arrData=[[NSMutableArray alloc]init];
}
On didSelectRowAtIndexPath add your value into array.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arrData addObject:[YourDataArray objectAtIndex:indexPath.row]];
}
May be it will help you.
try this..
NSMutableArray *selectedIndexes ; // instance variable, do initialization in viewDidLoad
i am assuming that you are using didSelectRowAtIndexPath for selecting cell (i mean not a custom button action)
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
if ([selectedIndexes containsObject:indexPath])
{
[selectedIndexes removeObject:indexPath];
}
else
{
[selectedIndexes addObject:indexPath];
}
}
Now you can get all selected cells using index values in selectedIndexes array
for ex UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:1];
edit :
remove all objects from selectedIndexes after selection process is over
#interface RestTableViewController ()<UISearchBarDelegate>{
NSMutableSet *setTemp;
// NSMutableArray *setTemp;
}
In ViewDidLoad
- (void)viewDidLoad {
[super viewDidLoad];
setTemp = [[NSMutableSet alloc] initWithCapacity:1];
. . .
}
In cellForRowAtIndexPath
cell.selectionStyle = UITableViewCellSelectionStyleNone;
[self markCell:cell atIndex:indexPath.row];
Create a Method
- (void)markCell:(UITableViewCell *)cell atIndex:(NSInteger)index{
if ([setTemp containsObject:[NSNumber numberWithInteger:index]]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
In didSelectRowAtIndexPath
[tableView deselectRowAtIndexPath:indexPath animated:YES];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
{
// Restaurent is my Object File
Restaurent *obj = [restMutableArray objectAtIndex:indexPath.row];
if ([setTemp containsObject:[NSNumber numberWithInteger:indexPath.row]]) {
[setTemp removeObject:[NSNumber numberWithInteger:indexPath.row]];
// tempMainArray is an array which manages the title of selected or deselected Rows . . .
[tempMainArray removeObject:obj.strTitle];
NSLog(#"Selected Row Data %#",tempMainArray);
}
else {
[setTemp addObject:[NSNumber numberWithInteger:indexPath.row]];
[tempMainArray addObject:obj.strTitle];
NSLog(#"Selected Row Data %#",tempMainArray);
}
[self markCell:cell atIndex:indexPath.row];
}
To Select All The Cell
#pragma mark : Select All Data Method. . .
- (IBAction)actionBtnClicked:(id)sender {
{
[setTemp removeAllObjects];
for (int i = 0 ; i < [restMutableArray count]; i++) {
Restaurent *obj = [restMutableArray objectAtIndex:i];
[tempMainArray addObject:obj.strTitle];
[setTemp addObject:#(i)];
}
NSLog(#"%#",tempMainArray);
[self.tableView reloadData];
}

Tapping the cell selections does not change the cell accessory to a checkmark

Can someone help me? I've been following along with Apple's official Objective C tutorial (the one that has us create a To Do List).
I'm stuck at the part where tapping the cell item displays/removes a checkmark. It's not happening.
Here's my implementation file if someone could take a look?
I've really tried my best to solve where I went wrong. I swear I tried my best to figure out everything on my own before posting here. Please, any help would be greatly appreciated!!
Thank you!
EDIT: So i put a breakpoint in my didSelectRowAtIndexPath method. It was not triggered when I tapped a table item, so it's not getting called when I tap items, right? Where do I look next?
//
// ToDoListTableViewController.m
// ToDoList
//
// Created by Kevin Zagala on 9/1/14.
// Copyright (c) 2014 Kevin Zagala. All rights reserved.
//
#import "ToDoListTableViewController.h"
#import "ToDoItem.h"
#interface ToDoListTableViewController ()
#property NSMutableArray *toDoItems;
#end
#implementation ToDoListTableViewController
- (IBAction)unwindToList:(UIStoryboardSegue *)segue
{
}
- (void)loadInitialData {
ToDoItem *item1 = [[ToDoItem alloc] init];
item1.itemName = #"Buy milk";
[self.toDoItems addObject:item1];
ToDoItem *item2 = [[ToDoItem alloc] init];
item2.itemName = #"Buy eggs";
[self.toDoItems addObject:item2];
ToDoItem *item3 = [[ToDoItem alloc] init];
item3.itemName = #"Read a book";
[self.toDoItems addObject:item3];
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.toDoItems = [[NSMutableArray alloc] init];
[self loadInitialData];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.toDoItems count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
ToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.itemName;
if (toDoItem.completed) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableview:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
ToDoItem *tappedItem = [self.toDoItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
[tableView reloadRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationNone];
}
#end
try this ..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
ToDoItem *toDoItem = [self.toDoItems objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.itemName;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.accessoryType == UITableViewCellAccessoryNone)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
try reloading whole tableview,
what u are doing should work, i tested your code by putting a dummy object with boolean value, it worked for me,
Note Both reloading the whole tableview and reloading the selected cell will work, only u are setting the correct boolean value
- (void)tableview:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:NO];
ToDoItem *tappedItem = [self.toDoItems objectAtIndex:indexPath.row];
tappedItem.completed = !tappedItem.completed;
// [tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone]; //comment this
[tableView reloadData]; //add this
}

uiTableViewCell Add row with and image and remove row with second tap

I've been trying to figuered this out for hours. I'm just plain old stuck here. What im trying to accomplish is basically inserting a row directly below the row just tapped in the tableview in addition i would like to add and image to the row and and make the image clickable to respond to its click event.
So here is my code.
I implemented (i belive) the nessesary methods to handle all the actions for the uitableview.
when the user taps the cell i handle that action by executing the following code.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (debug==1) {
NSLog(#"running line 225%# '%#'", self.class, NSStringFromSelector(_cmd));
}
Locations *location = nil;
Locations *tempObject = [[Locations alloc]init];
//test to see if we are looking for the search box or if we are essentially looking from the main view controller.
if (self.searchDisplayController.active) {
location= [self.searchResults objectAtIndex:indexPath.row];
NSLog(#"location : %#" ,location.locationName);
} else {
location = [self.locations objectAtIndex:indexPath.row];
NSLog(#"location : %#" ,location.locationName);
//set the new indexpath to 1 more then before so that we can essetially add a row right below the actual tapped item.
NSIndexPath *newPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section];
indexPath = newPath;
[self.locations insertObject:tempObject atIndex:indexPath.row ];
[tableView insertRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationBottom];
self.visibleCell =YES; //set this boolean variable so that we can add a specific row image to this var
// self.locations[0].isItVisible = YES;
}//ends the else statement.
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
the above code inserts an empty cell into my tableview.
however how can i set the cell so that its custom and not the same as the others. In other words my initial cells data-source are basically bound to an nsobject and a string property location-name. However when i go try to update the table cells in the above method i obviously cannot add an image into a string so I'm running in to a error.
so i tried to instead make the update on the
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
by basically checking if a variable is set to true or false but that turned out to be buggy because even when i scroll this method gets called.
How should i go about doing this. I think i have to do it all in the didselectrowindexaspath method. But i cant figured out how to change the newly inserted cell to contain an image only.
Any help would be appreciated.
EDIT
here is what im doing to try to add the image under the cellforrowindexpath method.
if(self.visibleCell==YES){
UIImage *clkImg = [UIImage imageNamed:#"alarm_clock.png"];
cell.imageView.image = clkImg;
}
Im a noob so im not sure im doing this correctly.
EDIT
this is the full cellforatindexpath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (debug==1) {
NSLog(#"running line 159 %# '%#'", self.class, NSStringFromSelector(_cmd));
}
// NSLog(#"cell for row at index path just got called");
//JAMcustomCell *myCell = [[JAMcustomCell alloc]init];
static NSString *CellIdentifier = #"ListPrototypeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Locations * locations = [[Locations alloc]init];
//tableView.backgroundColor = [UIColor blackColor];
// NSLog(#"this is visible '%hhd'", locations.isItVisible);
if(self.visibleCell==YES){
UIImage *clkImg = [UIImage imageNamed:#"alarm_clock.png"];
cell.imageView.image = clkImg;
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
locations = [self.searchResults objectAtIndex:indexPath.row];
}
else{
locations = [self.locations objectAtIndex:indexPath.row];
}
cell.textLabel.text = locations.locationName;
cell.textLabel.textColor = [UIColor whiteColor];
//cell.backgroundColor =[UIColor blackColor];
// cell.backgroundColor =[UIColor colorWithPatternImage:[UIImage imageNamed:#"Graytbl.fw.png"]];
cell.backgroundView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"blueTbl.fw.png"]];
cell.selectedBackgroundView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"blueTbl.fw.png"]];
// UIFont *myFont = [ UIFont fontWithName: #"Oswald" size: 25.0 ];
// cell.textLabel.font = myFont;
cell.textLabel.font= self.MyFont;//[UIFont fontWithName:#"Oswald-Regular.ttf" size:15];
return cell;
}
Try this approach, I used your idea of Bool
#pragma mark - Table View Data Source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(self.visibleCell){
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"imageViewCell" forIndexPath:indexPath];//ListPrototypeCell
UIImageView *imageVIew = (UIImageView *)[cell viewWithTag:1];
[imageVIew setImage:[UIImage imageNamed:#"alarm_clock.png"]];
return cell;
}else{
return [tableView dequeueReusableCellWithIdentifier:#"ListPrototypeCell" forIndexPath:indexPath];
}
}
#pragma mark - Table View Delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if(!self.visibleCell){
self.numberOfRows++;
self.visibleCell = YES;
NSIndexPath *indexPathCell = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0];
[self.tableView insertRowsAtIndexPaths:#[indexPathCell] withRowAnimation:UITableViewRowAnimationBottom];
}else{
self.numberOfRows--;
self.visibleCell = NO;
NSIndexPath *indexPathCell = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0];
[self.tableView deleteRowsAtIndexPaths:#[indexPathCell] withRowAnimation:UITableViewRowAnimationTop];
}
}
I created a demo project for you.
I hope it helps

ios Collapsable/expandable tableview on storyboard

i wanted to make collapsable/expandable tableview in which i have two headers product and services and each of them contains 10+ object with custom cell which contains checkmark on left side and label. i check for the tutorials but most of them are using .xib while my project is based on storyboard.
i check these tutorials, can anyone please help me regarding this.
https://www.cocoacontrols.com/controls/collapseclick
https://www.cocoacontrols.com/controls/ratreeview
https://www.cocoacontrols.com/controls/combobox-for-uitableview
I have found a great sample project on this at:
https://github.com/singhson/Expandable-Collapsable-TableView
It is very easy to understand and implement.
//
// ViewController.h
// expandableTV
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
NSMutableIndexSet *expandedSections;
}
#property (weak, nonatomic) IBOutlet UITableView *tbl_expandablecategory;
#end
//
// ViewController.m
// expandableTV
//
#import "ViewController.h"
#import "expandableTC.h"`
#interface ViewController ()
{
NSArray *jsonArray;
BOOL currentlyExpanded;
}
#end
#implementation ViewController
#synthesize tbl_expandablecategory;
NSMutableArray *arr_categorymenumodel;
- (void)viewDidLoad {
[super viewDidLoad];
arr_categorymenumodel=[[NSMutableArray alloc] init];
if (!expandedSections)
{
expandedSections = [[NSMutableIndexSet alloc] init];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 6;//[arr_categorymenumodel count];
}
- (BOOL)tableView:(UITableView *)tableView canCollapseSection:(NSInteger)section
{
return YES;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([self tableView:tableView canCollapseSection:section])
{
if ([expandedSections containsIndex:section])
{
return 2;
}
}
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row==0)
{
return 40;
}
return 270;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Configure the cell...
if (!indexPath.row)
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text =#"Room ";// [NSString stringWithFormat:#"%#",[[arr_categorymenumodel objectAtIndex:indexPath.section] valueForKey:#"CategoryName"]];
// cell.backgroundColor=[UIColor colorWithRed:237.0/255.0 green:237.0/255.0 blue:237.0/255.0 alpha:1.0];
cell.textLabel.font=[UIFont fontWithName:#"HelveticaNeue" size:20.0];
if (currentlyExpanded)
{
}
cell.accessoryView = [[UIImageView alloc]initWithImage: [UIImage imageNamed:#"rightarrow.png"]];
return cell;
}
else
{
expandableTC *cell = [tableView dequeueReusableCellWithIdentifier:#"Customcell"];
return cell;
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([self tableView:tableView canCollapseSection:indexPath.section])
{
if (!indexPath.row)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSInteger section = indexPath.section;
currentlyExpanded = [expandedSections containsIndex:section];
NSInteger rows;
NSMutableArray *tmpArray = [NSMutableArray array];
if (currentlyExpanded)
{
rows = [self tableView:tableView numberOfRowsInSection:section];
[expandedSections removeIndex:section];
cell.accessoryView = [[UIImageView alloc]initWithImage: [UIImage imageNamed:#"rightarrow.png"]];
}
else
{
[expandedSections addIndex:section];
rows = [self tableView:tableView numberOfRowsInSection:section];
cell.accessoryView = [[UIImageView alloc]initWithImage: [UIImage imageNamed:#"downarrow.png"]];
}
for (int i=1; i<rows; i++)
{
NSIndexPath *tmpIndexPath = [NSIndexPath indexPathForRow:i inSection:section];
[tmpArray addObject:tmpIndexPath];
}
if (currentlyExpanded)
{
[tableView deleteRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationFade];
}
else
{
[tableView insertRowsAtIndexPaths:tmpArray
withRowAnimation:UITableViewRowAnimationFade];
}
}
}
}
#end

How to create dynamic UITableView cells using iPhone SDK

In my app, I have UITableView in which first cell & last three cell's contents are fixed. But in between those cell's contents are different as per array count & content.
E.g: 1st cell+ array count + last three cells.
The array count different all times.
How can make the table view as I explaining above.
//Working code for 1st cell+[dynamic array]+last three Fixed cells
#import "tableTOViewController.h"
#interface tableTOViewController ()
#end
#implementation tableTOViewController
- (void)viewDidLoad
{
myArray=[[NSArray alloc] init];
myArray=[NSArray arrayWithObjects:#"Aman",#"Atul",#"Karan",#"Yen",#"Chan",#"Lee", nil];
lastFixedArray=[[NSArray alloc] init];
lastFixedArray=[NSArray arrayWithObjects:#"Snakes",#"Food",#"Drink", nil];
tblView.delegate=self;
tblView.dataSource=self;
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myArray count]+4;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"cellIdentifier";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if (indexPath.row==0)
cell.textLabel.text=#"First Cell";
else if (indexPath.row>[myArray count])
cell.textLabel.text=[lastFixedArray objectAtIndex:([indexPath row]-[myArray count]-1)];
else
cell.textLabel.text=[myArray objectAtIndex:indexPath.row-1];
return cell;
}
#end
If you want to add subviews to last three cells then you can use following condition
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"cellIdentifier";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if (indexPath.row==0)
cell.textLabel.text=#"First Cell";
else if (indexPath.row>[myArray count])
{
int k=([indexPath row]-[myArray count]-1);
switch (k) {
case 0:
[cell.contentView addSubview:thirdLastView];
break;
case 1:
[cell.contentView addSubview:secondLastView];
break;
case 2:
[cell.contentView addSubview:lastView];
break;
}
cell.textLabel.text=[lastFixedArray objectAtIndex:k];
}
else
cell.textLabel.text=[myArray objectAtIndex:indexPath.row-1];
return cell;
}
In your numberOfRows method, return value as
4 + [array count];
In cellForRowAtIndexPath do a switch on indexPath.row and accordingly fill your cell contents.

Resources