I am using UITableView in which number of sections are created dynamically according to the data. From 1 to 12. Section names are the names of months. How can I check w.r.t to the sections name. My code is
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [sectionArray count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionArray objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
int count = 0;
for(int counter=0; counter<[sectionArray count]; counter++)
{
NSString *month = [sectionArray objectAtIndex:counter];
if([month isEqualToString:#"October"])
{
count = [octoberArray count];
}
else if([month isEqualToString:#"November"])
{
count = [novemberArray count];
}
else if([month isEqualToString:#"December"])
{
count = [decemberArray count];
}
else if([month isEqualToString:#"January"])
{
count = [januaryArray count];
}
else if([month isEqualToString:#"February"])
{
count = [febuaryArray count];
}
else if([month isEqualToString:#"March"])
{
count = [marchArray count];
}
else if([month isEqualToString:#"April"])
{
count = [aprilArray count];
}
else if([month isEqualToString:#"May"])
{
count = [mayArray count];
}
else if([month isEqualToString:#"June"])
{
count = [juneArray count];
}
else if([month isEqualToString:#"July"])
{
count = [julyArray count];
}
else if([month isEqualToString:#"August"])
{
count = [augustArray count];
}
else
{
count = [septemberArray count];
}
}
return count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
HistoryCell *cell = (HistoryCell *)[tableView dequeueReusableCellWithIdentifier:#"historyCell"];
if(cell == nil)
{
cell = [[[NSBundle mainBundle]loadNibNamed:#"HistoryCell" owner:self options:nil] objectAtIndex:0];
}
for(int counter=0; counter<[sectionArray count]; counter++)
{
NSString *month = [sectionArray objectAtIndex:counter];
if([month isEqualToString:#"October"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[octoberGlassesArray objectAtIndex:indexPath.row]];
cell.unitLabel.text = #"Unit";
cell.dateLabel.text = [octoberArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"November"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[novemberGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [novemberArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"December"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[decemberGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [decemberArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"January"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[januaryGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [januaryArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"February"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[febuaryGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [febuaryArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"March"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[marchGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [marchArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"April"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[aprilGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [aprilArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"May"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[mayGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [mayArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"June"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[juneGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [juneArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"July"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[julyGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [julyArray objectAtIndex:indexPath.row];
}
else if([month isEqualToString:#"August"])
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[augustGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [augustArray objectAtIndex:indexPath.row];
}
else
{
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[septemberGlassesArray objectAtIndex:indexPath.row]];
cell.dateLabel.text = [septemberArray objectAtIndex:indexPath.row];
}
}
return cell;
}
The application crashes. How can I fix this issue?
I'm sure you don't clearly understand how UITableViewDataSource works. But if I understand your idea correctly the code below should fix the problem:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [sectionArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSArray *yourMonthArray = //Here get an array for adequate month
return [yourMonthArray count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSArray *arr = #[#"January",#"February",...,#"December"];
// asserts are optional. Just for sure you initialized your data well.
NSAssert(arr.count == 12, #"The number of months is not valid");
NSAssert(arr.count == [sectionArray count], #"Number of months is different than number of sections");
return arr[section];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HistoryCell *cell = (HistoryCell *)[tableView dequeueReusableCellWithIdentifier:#"historyCell"];
if(cell == nil)
{
// Please consider using UINib instread.
cell = [[[NSBundle mainBundle]loadNibNamed:#"HistoryCell" owner:self options:nil] objectAtIndex:0];
}
NSString *month = [sectionArray objectAtIndex:indexpath.section];
cell.glassesLabel.text = [NSString stringWithFormat:#"%# Glasses",[octoberGlassesArray objectAtIndex:indexPath.section]];
cell.unitLabel.text = #"Unit";
NSArray *yourMonthArray = //Here get an array for adequate month
cell.dateLabel.text = yourMonthArray[indexPath.row];
return cell;
}
Whats Happening
I have a UITableView, what i do is display the first ten records from the database then when the user scrolls to the end i retrieve just one record from the database and then add this to the array and reload the data but the UITableView seems to flash. I have added some code that will sync the data correctly so that when i scroll down and retrieve the record i don't get duplicate data.
Question
How can i stop the flashing or flickering when i add new data to the UITableView?
CODE
This is where i add the new data when i scroll down to the bottom:
-(void)renderScrollThreadInfo:(NSDictionary*)dic{
NSDictionary *thread = [dic objectForKey:#"thread"];
if((NSNull*)thread != [NSNull null]){
int t_ID;
int t_U_ID;
int t_C_ID;
NSString *t_Name;
NSString *t_Description;
NSDate *t_Created;
int t_Flagged;
int t_Rated;
NSString *firstName;
NSString *lastName;
NSString *categoryName;
for(NSDictionary *dict in thread)
{
if((NSNull *)[dict objectForKey:#"T_ID"] != [NSNull null]){
t_ID = [[dict objectForKey:#"T_ID"] intValue];
}
if((NSNull *)[dict objectForKey:#"T_U_ID"] != [NSNull null]){
t_U_ID = [[dict objectForKey:#"T_U_ID"] intValue];
}
if((NSNull *)[dict objectForKey:#"T_C_ID"] != [NSNull null]){
t_C_ID = [[dict objectForKey:#"T_C_ID"] intValue];
}
if((NSNull *)[dict objectForKey:#"T_Name"] != [NSNull null]){
t_Name = [dict objectForKey:#"T_Name"];
}
if((NSNull *)[dict objectForKey:#"T_Description"] != [NSNull null]){
t_Description = [dict objectForKey:#"T_Description"];
}
if((NSNull *)[dict objectForKey:#"T_Created"] != [NSNull null]){
NSString *timestampString = [dict objectForKey:#"T_Created"];
double timestampDate = [timestampString doubleValue];
t_Created = [NSDate dateWithTimeIntervalSince1970:timestampDate];
}
if((NSNull *)[dict objectForKey:#"T_Flagged"] != [NSNull null]){
t_Flagged = [[dict objectForKey:#"T_Flagged"] intValue];
}
if((NSNull *)[dict objectForKey:#"T_Rated"] != [NSNull null]){
t_Rated = [[dict objectForKey:#"T_Rated"] intValue];
}
if((NSNull *)[dict objectForKey:#"U_FirstName"] != [NSNull null]){
firstName = [dict objectForKey:#"U_FirstName"];
}
if((NSNull *)[dict objectForKey:#"U_LastName"] != [NSNull null]){
lastName = [dict objectForKey:#"U_LastName"];
}
if((NSNull *)[dict objectForKey:#"C_Name"] != [NSNull null]){
categoryName = [dict objectForKey:#"C_Name"];
}
ThreadInfo *threadObj = [ThreadInfo new];
threadObj.iD = t_ID;
threadObj.userId = t_U_ID;
threadObj.catId = t_C_ID;
threadObj.name = t_Name;
threadObj.description = t_Description;
threadObj.timeStampCreated = t_Created;
threadObj.flagged = t_Flagged;
threadObj.rated = t_Rated;
threadObj.firstName = firstName;
threadObj.lastName = lastName;
threadObj.category = categoryName;
BOOL foundThreadId = false;
for(int i = 0; i < [threadsArray count] - 1; i++){
ThreadInfo *tmpThreadInfo = (ThreadInfo*)[threadsArray objectAtIndex:i];
if(tmpThreadInfo.iD == t_ID){
foundThreadId = true;
}
}
if(!foundThreadId){
[threadsArray addObject:threadObj];
}
}
[tableViewThreads reloadData];
}
}
This is the code that calls a php script to get the next record:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(tableViewThreads == tableView){
//NSLog(#"%d %d",[indexPath row], [threadsArray count] - 1);
if ([indexPath row] == [threadsArray count] - 2) {
ThreadInfo *threadInfo = (ThreadInfo*)[threadsArray objectAtIndex:[threadsArray count] - 1];
int tid = threadInfo.iD;
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 3) Load picker in background
dispatch_async(concurrentQueue, ^{
NSString *searchItem = textFieldSearchThreads.text;
NSString *myRequestString = [NSString stringWithFormat:#"Category=%d&TID=%d&SearchItem=%#",rowCategory, tid, searchItem];
NSString *response = [self setupPhpCall:myRequestString :#"getThread.php"];
dispatch_async(dispatch_get_main_queue(), ^{
if(response.length > 0){
[self renderScrollThreadInfo:[response JSONValue]];
}
});
});
}
}
if(tableViewPosts == tableView){
//NSLog(#"%d %d",[indexPath row], [threadsArray count] - 1);
if ([indexPath row] == [postsArray count] - 1) {
PostInfo *postInfo = (PostInfo*)[postsArray objectAtIndex:[postsArray count] - 1];
int pid = postInfo.iD;
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 3) Load picker in background
dispatch_async(concurrentQueue, ^{
NSString *myRequestString = [NSString stringWithFormat:#"TID=%d&PID=%d", chatThreadId, pid];
NSString *response = [self setupPhpCall:myRequestString :#"getStandalonePost.php"];
dispatch_async(dispatch_get_main_queue(), ^{
if(response.length > 0){
//[tableViewPosts scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];
[self renderScrollPostInfo:[response JSONValue]];
}
});
});
}
}
}
This is the code where a set up my Custom Cells with data:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(tableViewThreads == tableView){
NSString *cellIdentifier = #"cell";
ThreadTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
ThreadInfo *threadInfo = (ThreadInfo*)[self.threadsArray objectAtIndex:indexPath.row];;
if (cell == nil)
{
cell = [[ThreadTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
[cell setupView:threadInfo];
}
cell.labelFirstName.text = [NSString stringWithFormat:#"%# %#", threadInfo.firstName,threadInfo.lastName];
cell.labelTimestamp.text = [NSDateFormatter localizedStringFromDate:threadInfo.timeStampCreated dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
cell.labelTimestamp.text = [cell.labelTimestamp.text stringByReplacingOccurrencesOfString:#"AM" withString:#""];
cell.labelTimestamp.text = [cell.labelTimestamp.text stringByReplacingOccurrencesOfString:#"PM" withString:#""];
cell.labelThreadName.text = threadInfo.name;
//cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
if(tableViewPosts == tableView){
NSString *cellIdentifier = #"cell2";
PostTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
PostInfo *postInfo = (PostInfo*)[self.postsArray objectAtIndex:indexPath.row];
if (cell == nil)
{
cell = [[PostTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
[cell setupView:postInfo];
}
cell.labelUserName.text = [NSString stringWithFormat:#"%# %# posted...", postInfo.firstName,postInfo.lastName];
cell.labelCreated.text = [NSDateFormatter localizedStringFromDate:postInfo.timeStampCreated dateStyle:NSDateFormatterMediumStyle timeStyle:NSDateFormatterMediumStyle];
cell.labelCreated.text = [cell.labelCreated.text stringByReplacingOccurrencesOfString:#"AM" withString:#""];
cell.labelCreated.text = [cell.labelCreated.text stringByReplacingOccurrencesOfString:#"PM" withString:#""];
cell.labelMessage.text = postInfo.message;
return cell;
//[cell.contentView addSubview:[self setupThreadItem:threadInfo]];
}
return nil;
}
Instead of calling [UITableView reloadData] when you receive new data, use [UITableView insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
Rows of Level 1 should expand and collapse. Suppose if Row 0 is open - that means its status is 1 - and next row's status is 0, if I click on next row whose status is 0, then the row whose status is 1 should get closed.
How can I do that?
Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
dictBtnStatus = [[NSMutableDictionary alloc] init];
arraylist = [[NSMutableArray alloc] init];
array5 = [[NSMutableArray alloc] init];
array1 = [[NSMutableArray alloc] init];
objects = #[#"Medical Services In Chicago", #"Medical Services On Campus", #"ABC", #"California"];
// objects = #[#"Medical Services In Chicago", #"Medical Services On Campus"];
arrObjectValueChicago = #[#"Ronald McDonald® Children's Hospital of Loyola", #"Burn Centers", #"Gottlieb Hospitals"];
arrObjectValueCampus = #[#"Cardinal Bernardin Cancer Center1", #"Center for Heart & Vascular Medicine2", #"ABC"];
for (int i = 0; i < [arrObjectValueCampus count]; i++) {
dictListCampus1 = [[NSDictionary alloc] initWithObjectsAndKeys:#"2", #"level",[arrObjectValueCampus objectAtIndex:i], #"name", nil];
[array5 addObject:dictListCampus1];
}
NSDictionary *dictListCampus = [[NSDictionary alloc] initWithObjectsAndKeys:#"Wellness Centers", #"name", #"1", #"level", array5, #"Objects", nil];
NSMutableArray *array6 = [[NSMutableArray alloc] initWithObjects:dictListCampus, nil];
array3 = [[NSMutableArray alloc] init ];
for (int i = 0; i < [arrObjectValueChicago count]; i++){
dictList3 = [[NSDictionary alloc]initWithObjectsAndKeys:#"2", #"level",[arrObjectValueChicago objectAtIndex:i], #"name", nil];
[array3 addObject:dictList3];
}
NSDictionary *dictList2 = [[NSDictionary alloc] initWithObjectsAndKeys:#"Hospitals", #"name", #"1", #"level", array3, #"Objects", nil];
NSMutableArray *array2 = [[NSMutableArray alloc] initWithObjects:dictList2, nil];
for (int i = 0; i < [objects count]; i++) {
if (i == 0) {
dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:0], #"name", #"0", #"level", array2, #"Objects", nil];
[array1 addObject:dictionary];
} else if (i == 1) {
dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:1], #"name", #"0", #"level", array6, #"Objects", nil];
[array1 addObject:dictionary];
} else if (i == 2) {
dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:2], #"name", #"0", #"level", array6, #"Objects", nil];
[array1 addObject:dictionary];
} else {
dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:3], #"name", #"0", #"level", array2, #"Objects", nil];
[array1 addObject:dictionary];
}
}
dictList = [[NSDictionary alloc] initWithObjectsAndKeys:array1, #"Objects", nil];
arrayOriginal = [dictList valueForKey:#"Objects"];
[arraylist addObjectsFromArray:arrayOriginal];
}
#pragma mark - TableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [arraylist count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// static NSString *CellIdentifier = #"CustomCellIdentifier";
NSUInteger IndentLevel = [[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (IndentLevel == 0) {
CustomCellHeader *cell = (CustomCellHeader *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil) {
[[NSBundle mainBundle]loadNibNamed:#"CustomCellHeader" owner:self options:nil];
cell = self.headercell;
self.headercell = nil;
}
cell.lblHeader.text = [[arraylist objectAtIndex:indexPath.row] valueForKey:#"name"];
[cell setIndentationLevel:[[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
NSLog(#"indexFor level 0 ::%# %d",cell.lblHeader.text,indexPath.row);
return cell;
} else if (IndentLevel == 1) {
CustomCellSubHeader *cell = (CustomCellSubHeader *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (!cell) {
[[NSBundle mainBundle]loadNibNamed:#"CustomCellSubHeader" owner:self options:nil];
cell = self.subheadercell;
self.subheadercell = nil;
NSLog(#"dicbtn %#", dictBtnStatus);
NSString *strName = [[arraylist objectAtIndex:indexPath.row]valueForKey:#"name"];
NSString *str = [dictBtnStatus objectForKey:strName];
NSLog(#"indexFor level 1 ::%# %d", strName, indexPath.row);
if ([str isEqualToString:#"1"]) {
[cell.btnarrow setImage:[UIImage imageNamed:#"dwn1_arow.png"] forState:UIControlStateNormal];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_active.png"]];
}
cell.lblSubHeader.text = strName;
cell.imgShadow.hidden = YES;
[cell setIndentationLevel:[[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
}
return cell;
} else if (IndentLevel == 2) {
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil) {
[[NSBundle mainBundle]loadNibNamed:#"CustomCell" owner:self options:nil];
cell = self.cells;
self.cells = nil;
}
cell.txtAddress.text = [[arraylist objectAtIndex:indexPath.row] valueForKey:#"name"];
[cell.btnCall addTarget:self action:#selector(btnCall:) forControlEvents:UIControlEventTouchUpInside];
[cell setIndentationLevel:[[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
return cell;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tblist deselectRowAtIndexPath:indexPath animated:YES];
NSUInteger IndentLevel = [[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue];
NSString *strName = [[arraylist objectAtIndex:indexPath.row] valueForKey:#"name"];
CustomCellSubHeader *cell = ((CustomCellSubHeader*)[tblist cellForRowAtIndexPath:indexPath]);
if (IndentLevel == 1) {
[dictBtnStatus setValue:#"0" forKey:strName];
[cell.btnarrow setImage:[UIImage imageNamed:#"gry_arrow.png"] forState:UIControlStateNormal];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_default.png"]];
}
NSDictionary *d = [arraylist objectAtIndex:indexPath.row];
if ([d valueForKey:#"Objects"]) {
NSArray *ar = [d valueForKey:#"Objects"];
BOOL isAlreadyInserted = NO;
for (NSDictionary *dInner in ar) {
NSInteger index = [arraylist indexOfObjectIdenticalTo:dInner];
isAlreadyInserted = (index > 0 && index != NSIntegerMax);
if (IndentLevel == 1) {
[dictBtnStatus setValue:#"0" forKey:strName];
[cell.btnarrow setImage:[UIImage imageNamed:#"gry_arrow.png"] forState:UIControlStateNormal];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_default.png"]];
} else if (IndentLevel == 0) {
NSString *strStatus = [dictBtnStatus objectForKey:strName];
if ([strStatus isEqualToString:#"1"]) {
// NSDictionary *dict = [arraylist objectAtIndex:previousRow];
// if ([dict valueForKey:#"Objects"]) {
NSArray * array = [[arraylist objectAtIndex:previousRow]valueForKey:#"Objects"];
[self miniMizeThisRows:array];
}
}
if (isAlreadyInserted) break;
}
if (isAlreadyInserted) {
if ([arraylist count] - 1 && IndentLevel == 1) {
cell.imgShadow.hidden = NO;
}
if (IndentLevel == 1) {
[dictBtnStatus setValue:#"0" forKey:strName];
[cell.btnarrow setImage:[UIImage imageNamed:#"gry_arrow.png"] forState:UIControlStateNormal];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_default.png"]];
} else if (IndentLevel == 0) {
[dictBtnStatus setValue:#"0" forKey:strName];
}
[self miniMizeThisRows:ar];
} else {
NSUInteger count=indexPath.row + 1;
NSMutableArray *arCells = [NSMutableArray array];
for (NSDictionary *dInner in ar) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
previousRow = [indexPath row];
if (IndentLevel == 1) {
[dictBtnStatus setValue:#"1" forKey:strName];
[cell.btnarrow setImage:[UIImage imageNamed:#"dwn1_arow.png"] forState:UIControlStateNormal];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_active.png"]];
} else if (IndentLevel == 0) {
[dictBtnStatus setValue:#"1" forKey:strName];
}
[arraylist insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationNone];
}
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger indentLevel = [[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue];
if (indentLevel == 0) {
return 40;
} else if (indentLevel == 1) {
return 25;
} else if (indentLevel == 2) {
CustomCell *cell = ((CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"]);
CGSize maximumSize = CGSizeMake(300, 9999);
UIFont *myFont = [UIFont fontWithName:#"Arial" size:11.5];
CGSize myStringSize = [cell.txtAddress.text sizeWithFont:myFont constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];
[cell.txtAddress setFrame:CGRectMake(cell.txtAddress.frame.origin.x, cell.txtAddress.frame.origin.y, cell.txtAddress.frame.size.width, myStringSize.height)];
if (myStringSize.height > 80) {
myStringSize.height = 50;
[cell.txtAddress setFrame:CGRectMake(cell.txtAddress.frame.origin.x, cell.txtAddress.frame.origin.y, cell.txtAddress.frame.size.width, myStringSize.height)];
cell.txtAddress.scrollEnabled = YES;
} else {
cell.txtAddress.scrollEnabled = YES;
myStringSize.height = 40;
}
return myStringSize.height+ 50;
} else return 25;
}
#pragma mark - TableAnimation
- (void)miniMizeThisRows:(NSArray *)ar {
for(NSDictionary *dInner in ar) {
NSUInteger indexToRemove = [arraylist indexOfObjectIdenticalTo:dInner];
NSArray *arInner = [dInner valueForKey:#"Objects"];
if (arInner && [arInner count] > 0) {
[self miniMizeThisRows:arInner];
}
if ([arraylist indexOfObjectIdenticalTo:dInner]!= NSNotFound) {
[arraylist removeObjectIdenticalTo:dInner];
[tblist deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexToRemove inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}
}
}
- (void)viewDidLoad {
[super viewDidLoad];
dictBtnStatus = [[NSMutableDictionary alloc] init];
arraylist = [[NSMutableArray alloc] init];
array5 = [[NSMutableArray alloc] init];
array1 = [[NSMutableArray alloc] init];
objects = #[#"Medical Services In Chicago", #"Medical Services On Campus", #"ABC", #"California"];
// objects = #[#"Medical Services In Chicago", #"Medical Services On Campus"];
arrObjectValueChicago = #[#"Ronald McDonald® Children's Hospital of Loyola", #"Burn Centers", #"Gottlieb Hospitals"];
arrObjectValueCampus = #[#"Cardinal Bernardin Cancer Center1", #"Center for Heart & Vascular Medicine2", #"ABC"];
for (int i = 0; i < [arrObjectValueCampus count]; i++) {
dictListCampus1 = [[NSDictionary alloc]initWithObjectsAndKeys:#"2", #"level",[arrObjectValueCampus objectAtIndex:i], #"name", nil];
[array5 addObject:dictListCampus1];
}
NSDictionary *dictListCampus = [[NSDictionary alloc]initWithObjectsAndKeys:#"Wellness Centers", #"name", #"1", #"level", array5, #"Objects", nil];
NSMutableArray *array6 = [[NSMutableArray alloc] initWithObjects:dictListCampus, nil];
NSDictionary *dictListCampus2 = [[NSDictionary alloc] initWithObjectsAndKeys:#"Wellness Centers123", #"name", #"1", #"level", array5, #"Objects", nil];
NSMutableArray *array61 = [[NSMutableArray alloc] initWithObjects:dictListCampus2, nil];
array3 = [[NSMutableArray alloc] init];
for (int i = 0; i < [arrObjectValueChicago count]; i++) {
dictList3 = [[NSDictionary alloc] initWithObjectsAndKeys:#"2", #"level",[arrObjectValueChicago objectAtIndex:i], #"name", nil];
[array3 addObject:dictList3];
}
NSDictionary *dictList2 = [[NSDictionary alloc] initWithObjectsAndKeys:#"Hospitals", #"name", #"1", #"level", array3, #"Objects", nil];
NSMutableArray *array2 = [[NSMutableArray alloc] initWithObjects:dictList2, nil];
for (int i = 0; i < [objects count]; i++) {
if (i == 0) {
dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:0], #"name", #"0", #"level", array2, #"Objects", nil];
[array1 addObject:dictionary];
} else if (i == 1) {
dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:1], #"name", #"0", #"level", array6, #"Objects", nil];
[array1 addObject:dictionary];
} else if (i == 2) {
dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:2], #"name", #"0", #"level", array61, #"Objects", nil];
[array1 addObject:dictionary];
}
// else {
// dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:[objects objectAtIndex:3], #"name", #"0", #"level", array2, #"Objects", nil];
// [array1 addObject:dictionary];
//}
}
dictList = [[NSDictionary alloc] initWithObjectsAndKeys:array1, #"Objects", nil];
NSLog(#"DictList :: %#", dictList);
arrayOriginal = [dictList valueForKey:#"Objects"];
NSLog(#"Array Original :: %#", arrayOriginal);
[arraylist addObjectsFromArray:arrayOriginal];
//[tblist.delegate tableView:tblist didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
//[tblist.delegate tableView:tblist didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:1 inSection:0]];
}
#pragma mark - TableView
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [arraylist count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//static NSString *CellIdentifier = #"CustomCellIdentifier";
NSUInteger IndentLevel = [[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (IndentLevel == 0) {
CustomCellHeader *cell = (CustomCellHeader *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil) {
[[NSBundle mainBundle]loadNibNamed:#"CustomCellHeader" owner:self options:nil];
cell = self.headercell;
self.headercell = nil;
}
cell.lblHeader.text = [[arraylist objectAtIndex:indexPath.row] valueForKey:#"name"];
[cell setIndentationLevel:[[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
NSLog(#"indexFor level 0 ::%# %d",cell.lblHeader.text, indexPath.row);
return cell;
} else if (IndentLevel == 1) {
CustomCellSubHeader *cell = (CustomCellSubHeader *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (!cell) {
[[NSBundle mainBundle]loadNibNamed:#"CustomCellSubHeader" owner:self options:nil];
cell = self.subheadercell;
self.subheadercell = nil;
NSLog(#"dicbtn %#", dictBtnStatus);
}
NSString *strName = [[arraylist objectAtIndex:indexPath.row] valueForKey:#"name"];
NSString *str = [dictBtnStatus objectForKey:strName];
NSLog(#"indexFor level 1 ::%# %d", strName, indexPath.row);
if ([str isEqualToString:#"1"]) {
[cell.btnarrow setImage:[UIImage imageNamed:#"dwn1_arow.png"] forState:UIControlStateNormal];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_active.png"]];
}
// else {
// [cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_default.png"]];
//}
cell.lblSubHeader.text = strName;
[cell setIndentationLevel:[[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
if (indexPath.row == arraylist.count - 1) {
cell.imgShadow.hidden = NO;
}
return cell;
} else if (IndentLevel == 2) {
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
if (cell == nil) {
[[NSBundle mainBundle]loadNibNamed:#"CustomCell" owner:self options:nil];
cell = self.cells;
self.cells = nil;
}
cell.txtAddress.text = [[arraylist objectAtIndex:indexPath.row] valueForKey:#"name"];
[cell.btnCall addTarget:self action:#selector(btnCall:) forControlEvents:UIControlEventTouchUpInside];
[cell setIndentationLevel:[[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue]];
return cell;
}
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCellSubHeader *cell;
if ([[tblist cellForRowAtIndexPath:indexPath] isKindOfClass:[CustomCellSubHeader class]]) {
cell = (CustomCellSubHeader*)[tblist cellForRowAtIndexPath:indexPath];
UIImage *img = [cell.btnarrow imageForState:UIControlStateNormal];
if ([img isEqual:[UIImage imageNamed:#"dwn1_arow.png"]]) {
[cell.btnarrow setImage:[UIImage imageNamed:#"gry_arrow.png"] forState:UIControlStateNormal];
[dictBtnStatus setValue:#"0" forKey:cell.lblSubHeader.text];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_default.png"]];
cell.imgShadow.hidden = NO;
} else {
[cell.btnarrow setImage:[UIImage imageNamed:#"dwn1_arow.png"] forState:UIControlStateNormal];
dictBtnStatus = [[NSMutableDictionary alloc] init];
[dictBtnStatus setValue:#"1" forKey:cell.lblSubHeader.text];
[cell.imgSubHeader setImage:[UIImage imageNamed:#"tab_active.png"]];
cell.imgShadow.hidden = YES;
}
}
NSMutableArray *arrIndex = [[NSMutableArray alloc] init];
NSUInteger IndentLevel = [[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue];
if (IndentLevel == 0) {
arrLast = [[NSMutableArray alloc] init];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *d = [arraylist objectAtIndex:indexPath.row];
if ([d valueForKey:#"Objects"]) {
NSArray *ar = [d valueForKey:#"Objects"];
BOOL isAlreadyInserted = NO;
for (NSDictionary *dInner in ar) {
NSInteger index = [arraylist indexOfObjectIdenticalTo:dInner];
isAlreadyInserted = (index > 0 && index != NSIntegerMax);
if (isAlreadyInserted) break;
}
if (isAlreadyInserted) {
[self miniMizeThisRows:ar];
} else {
NSUInteger count = indexPath.row + 1;
NSMutableArray *arCells = [NSMutableArray array];
for (NSDictionary *dInner in ar) {
[arCells addObject:[NSIndexPath indexPathForRow:count inSection:0]];
[arrLast addObject:dInner];
[arraylist insertObject:dInner atIndex:count++];
}
[tableView insertRowsAtIndexPaths:arCells withRowAnimation:UITableViewRowAnimationBottom];
}
}
//NSUInteger IndentLevel = [[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue];
if (IndentLevel == 0) {
NSMutableIndexSet *discardedItems = [NSMutableIndexSet indexSet];
for (int i = 0 ; i < arraylist.count; i++) {
NSDictionary *dic = [arraylist objectAtIndex:i];
if ([[dic valueForKey:#"level"] intValue] != 0) {
NSInteger index = [arrLast indexOfObjectIdenticalTo:dic];
if ((index >= 0 && index != NSIntegerMax)) {
} else {
[discardedItems addIndex:i];
[arrIndex addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
}
}
if (discardedItems.count > 0) {
[arraylist removeObjectsAtIndexes:discardedItems];
[tblist deleteRowsAtIndexPaths:arrIndex withRowAnimation:UITableViewRowAnimationNone];
}
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger indentLevel = [[[arraylist objectAtIndex:indexPath.row] valueForKey:#"level"] intValue];
if (indentLevel == 0) {
return 40;
} else if (indentLevel == 1) {
return 25;
} else if (indentLevel == 2) {
CustomCell *cell = ((CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"]);
CGSize maximumSize = CGSizeMake(300, 9999);
UIFont *myFont = [UIFont fontWithName:#"Arial" size:11.5];
CGSize myStringSize = [cell.txtAddress.text sizeWithFont:myFont constrainedToSize:maximumSize lineBreakMode:NSLineBreakByWordWrapping];
[cell.txtAddress setFrame:CGRectMake(cell.txtAddress.frame.origin.x, cell.txtAddress.frame.origin.y, cell.txtAddress.frame.size.width, myStringSize.height)];
if (myStringSize.height > 80) {
myStringSize.height = 50;
[cell.txtAddress setFrame:CGRectMake(cell.txtAddress.frame.origin.x, cell.txtAddress.frame.origin.y, cell.txtAddress.frame.size.width, myStringSize.height)];
cell.txtAddress.scrollEnabled = YES;
} else {
cell.txtAddress.scrollEnabled = YES;
myStringSize.height = 40;
}
return myStringSize.height + 50;
} else return 25;
}
#pragma mark - TableAnimation
- (void)miniMizeThisRows:(NSArray *)ar {
for (NSDictionary *dInner in ar) {
NSUInteger indexToRemove = [arraylist indexOfObjectIdenticalTo:dInner];
NSArray *arInner=[dInner valueForKey:#"Objects"];
if (arInner && [arInner count] > 0) {
[self miniMizeThisRows:arInner];
}
if ([arraylist indexOfObjectIdenticalTo:dInner] != NSNotFound) {
[arraylist removeObjectIdenticalTo:dInner];
[tblist deleteRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:indexToRemove inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
}
}
}
#pragma mark - Buttons
- (IBAction)btnCall:(id)sender {
UIAlertView *Notpermitted = [[UIAlertView alloc] initWithTitle:#"Alert" message:#"Do you want to call on this number." delegate:nil cancelButtonTitle:#"NO" otherButtonTitles:#"YES", nil];
Notpermitted.delegate = self;
[Notpermitted tag];
[Notpermitted show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 1) {
NSString *strCall = [NSString stringWithFormat:#"tel://999-999-9999"];
NSURL *url = [NSURL URLWithString:strCall];
UIDevice *device = [UIDevice currentDevice];
if ([[device model] isEqualToString:#"iPhone"] ) {
[[UIApplication sharedApplication] openURL:url];
} else {
UIAlertView *Notpermitted = [[UIAlertView alloc] initWithTitle:#"Alert" message:#"Your device doesn't support this feature." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Notpermitted show];
}
}
}
see following tutorial
http://www.cocoanetics.com/2011/03/expandingcollapsing-tableview-sections/
www.alexandre-gomes.com/?p=482
Expand/collapse section in UITableView in iOS
I need to filter data in UITableview by text entered in UISearchbar. I followed this example but there data in NSMutableArray and I can't alter it under my requirements. My data is NSMutableDictionary. I'm stuck on this for long time.
My data:
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [[documentPaths lastObject] stringByAppendingPathComponent:#"data.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSMutableDictionary *resultDic = [[NSMutableDictionary alloc] init];
NSMutableArray *resultArray = [[NSMutableArray alloc] init];
NSDictionary *myDict = [NSDictionary dictionaryWithContentsOfFile:path];
sectionKeys = [NSMutableArray new];
sectionsTitle = [NSMutableArray new];
NSArray *tableArray = [myDict objectForKey:#"Black"];
[resultArray addObject:#"Black"];
[resultDic setValue:tableArray forKey:#"Black"];
[sectionsTitle addObject:[NSString stringWithFormat:#"%#", [tableData valueForKey:#"Black"]]];
[sectionCord addObject:[NSString stringWithFormat:#"%#", [tableData valueForKey:#"Coordinates"]]];
[sectionKeys addObject:#"Section1"];
self.tableData = resultDic;
self.sectionsTitle = resultArray;
[myTable reloadData];
My table:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return sectionKeys.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [sectionKeys objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
int rowCount;
if(self.isFiltered)
rowCount = [[filteredTableData objectForKey:[sectionsTitle objectAtIndex:section]] count];
else
rowCount = [[tableData objectForKey:[sectionsTitle objectAtIndex:section]] count];
return rowCount;
}
- (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(isFiltered){
NSDictionary *dict = [[filteredTableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Name"]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Address"]];
}
else{
NSDictionary *dict = [[tableData objectForKey:[sectionsTitle objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row];
cell.textLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Name"]];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", [dict objectForKey:#"Address"]];
}
return cell;
}
My search:
#pragma mark - SearchBar Delegate -
-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)text{
if(text.length == 0)
{
isFiltered = FALSE;
NSLog(#"false");
}
else
{
isFiltered = true;
NSLog(#"true");
filteredTableData = [[NSMutableDictionary alloc] init];
for (MyAnnotation* ann in tableData)
{
NSRange nameRange = [ann.title rangeOfString:text options:NSCaseInsensitiveSearch];
NSRange descriptionRange = [ann.description rangeOfString:text options:NSCaseInsensitiveSearch];
if(nameRange.location != NSNotFound || descriptionRange.location != NSNotFound)
{
[filteredTableData addObject:ann];
//error
}
}
}
[myTable reloadData];
}
First of all, you need to create a state/flag for the controller/data source, in order for it to know weather you are in search/filter mode.
Then, if you are in search mode, point the data source methods to the filteredArray.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
int numberOfSections = 0;
if (_searchMode)
{
numberOfSections = self.filteredDataDict.allKeys.count;
}
else
{
numberOfSections = self.tableData.allKeys.count;
}
return numberOfSections;
}
Hope it's understood.