Saturday 2 April 2011

UITableView


UITableView add buttons in section

First set the Delegate & Datasource of UITableView then proceed with below code.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
// create the parent view that will hold header Label
UIView* customView = [[UIView alloc] initWithFrame:CGRectMake(10.0, 0.0, 300.0, 44.0)];
// create the button object
UIButton * headerBtn = [[UIButton alloc] initWithFrame:CGRectZero];
headerBtn.backgroundColor = [UIColor clearColor];
headerBtn.opaque = NO;
headerBtn.frame = CGRectMake(10.0, 0.0, 100.0, 30.0);
[headerBtn setTitle:@"" forState:UIControlEventTouchUpInside];
[headerBtn addTarget:self action:@selector(ActionEventForButton:) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:headerBtn];

return customView;
}

Once a view is added to header then set the height for header since by default it would be something 20.,so you need to adjust it according to your View Height that has been added to header.

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 100.0;
}

Expand the table view cells 

Implemented for tableview header.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 32)];
UIButton *sectionButton = [UIButton buttonWithType:UIButtonTypeCustom];
sectionButton.tag = section;
sectionButton.frame = customView.frame;
[sectionButton addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];

UILabel *titleLabel = [[[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 32)] autorelease];
titleLabel.textAlignment = UITextAlignmentCenter;
titleLabel.backgroundColor = [UIColor clearColor];
titleLabel.font = [UIFont boldSystemFontOfSize:13];
titleLabel.textColor = [UIColor whiteColor];

NSString *tableHeader = @"table_header_down.png";
switch (section) {
case 0:
titleLabel.text = @"Section1";
tableHeader = showSection1 ? @"table_header_up.png" : @"table_header_down.png";
break;
case 1:
titleLabel.text = @"Section2";
tableHeader = showSection2 ? @"table_header_up.png" : @"table_header_down.png";
break;
case 2:
titleLabel.text = @"Section3";
tableHeader = showSection3 ? @"table_header_up.png" : @"table_header_down.png";
break;
case 3:
titleLabel.text = @"Section4";
tableHeader = showSection4 ? @"table_header_up.png" : @"table_header_down.png";
break;
default:
break;
}
[sectionButton setImage:[UIImage imageNamed:tableHeader] forState:UIControlStateNormal];
[customView addSubview:sectionButton];

[customView addSubview:titleLabel];

return [customView autorelease];
}


look at Retweets , list and More when i click retweet following appears

you can see that retweet expands and shows other listing and list and more slide below.
// Setting The Indentation for perticular Row
- (NSInteger)tableView:(UITableView *)tableView indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row == 0)
{
return 2;
}
return 2* [[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"Level"] intValue];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *mEBAgendaCell = @"Cell";
UILabel *label = nil;

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:mEBAgendaCell ];

if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) reuseIdentifier:mEBAgendaCell ] autorelease];

// Creating a Custom level

label = [[UILabel alloc] init];
[label setLineBreakMode:UILineBreakModeWordWrap];
[label setMinimumFontSize:15.f];
[label setNumberOfLines:0];
[label setTextColor:[UIColor darkGrayColor]];

[label setTag:7001];
[cell.contentView addSubview:label];
[label release];
}

if (!label)
label = (UILabel*)[cell viewWithTag:7001];

// Configure the cell...
if(indexPath.row == 0)
{

[label setText:kMeetingInfomation];
[label setBackgroundColor:[UIColor clearColor]];
float summaryHeight = [self tableView:tableView heightForRowAtIndexPath:indexPath];
[label setFrame:CGRectMake(43 , (summaryHeight/2) - 10, 320 - 14, 20)];

}
else {
NSString *text = [[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"TopicTitle"];
CGSize constraint = CGSizeMake(320- 43- ([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"Level"] intValue]*25), 20000.0f);

CGSize size = CGSizeMake(0, 0);

if([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"ParentId"] isEqualToString:@"Parent"])
{
[label setFont:[UIFont boldSystemFontOfSize:15.f]];
size = [text sizeWithFont:[UIFont boldSystemFontOfSize:15.f] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
}
else if(![[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"ParentId"] isEqualToString:@"Parent"]){
[label setFont:[UIFont systemFontOfSize:15.f]];
size = [text sizeWithFont:[UIFont systemFontOfSize:15.f] constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
}



[label setText:text];
[label setBackgroundColor:[UIColor clearColor]];
[label setFrame:CGRectMake(43 +([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"Level"] intValue]*25) , (MAX(size.height, 30.0f)+10)/2 - (size.height)/2, constraint.width, size.height)];


// Setting The Arrow Button Image
if([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"SubTopicCount"] intValue] !=0)
{

if([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"isOpen"] isEqual:[NSNumber numberWithInt:0]])
{
[cell.imageView setImage:[UIImage imageNamed:@"arrowRight.png"]];
}

if([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"isOpen"] isEqual:[NSNumber numberWithInt:1]])
{
[cell.imageView setImage:[UIImage imageNamed:@"arrowdown.png"]];

}

[cell.imageView setHidden:NO];
}


else if([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"SubTopicCount"] intValue] ==0)
{

[cell.imageView setImage:[UIImage imageNamed:@"Blank_Image.png"]];
[cell.imageView setHidden:YES];
}
}

[cell setBackgroundColor:[UIColor clearColor]];

[cell setSelectionStyle:UITableViewCellSelectionStyleNone];

[self setNormalImageForCellAtIndexPath:indexPath andCell:cell];

return cell;

}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(mSelectedParentID)
[mSelectedParentID release];

mSelectedParentID = nil;

if(indexPath.row != 0)
mSelectedParentID = [[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"ParentId"] retain];

if(mSelectedIndexPath)
{
[mSelectedIndexPath release];
mSelectedIndexPath = nil;
}

mSelectedIndexPath = [indexPath retain];

//New code added
//TODO_TA
//Move this post notification to background thread
if(indexPath.row ==0)
{
[self performSelector:@selector(getAgendaTopicDetaisWithID:) withObject:nil afterDelay:0.1];

[tableView reloadData];

return;
}
[mAppDelegate startProgressAtPoint:CGPointMake(kScreenWidth/2, kScreenHeight/2)];

[self performSelector:@selector(getAgendaTopicDetaisWithID:) withObject:[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] afterDelay:0.1];

//New coded added ends

// Checking if this Topic has Subtopics or not

int subTopicCount = [[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"SubTopicCount"] intValue];

if(subTopicCount == 0)
{
[tableView reloadData];
[tableView selectRowAtIndexPath:mSelectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone];

return;
}

// Getting Current Level
NSNumber *currentLevel = [[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"Level"];


// Getting current Topic ID
NSString *topicId = [[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"TopicID"];


// some Local Variable
NSMutableArray *tempArray;
NSMutableArray *temp ;
int flag = 0;
int no=0;


// Checking If It Is Already Fetached From Network (flag is used for this)

for(int l=0 ; l<[mAgendaCachedArray count];l++) {
if(l==0)
{
continue;
}
if([[[[mAgendaCachedArray objectAtIndex:l] objectForKey:kRow] objectForKey:@"TopicID"] isEqual:topicId] ) {
flag = 1; // Checking if this TopicId Has Subtopics or Not

if([[[[mAgendaCachedArray objectAtIndex:l] objectForKey:kRow] objectForKey:@"SubTopicCount"] intValue] !=0) {
flag =2; no=l+1; tempArray = [[NSMutableArray alloc]nitWithCapacity:0];
for(int k = l+1; k<[mAgendaCachedArray count];k++) {
// Getting The local array From Cached Array
if([[[[mAgendaCachedArray objectAtIndex:k] objectForKey:kRow] objectForKey:@"ParentId"] isEqual:topicId]) {
flag = 3;
[tempArray addObject:[mAgendaCachedArray objectAtIndex:k]]; } } } } }
if(flag == 2) {
// Fetching The Subtoipcs From dataBase
NSMutableArray *agendaSubTopicDetails = nil;
// Fetch Agenda Topics everytime, only in offline, fetch it from cached data.

//if([mAPIKey isEqualToString:kEmptyString])
if(![mAppDelegate getNetworkStatus])
agendaSubTopicDetails = [[EBDatabaseEngine sharedInstance] retrieveAgendaTopicsWithID:topicId];
if (agendaSubTopicDetails) {
temp =[agendaSubTopicDetails retain];
[agendaSubTopicDetails release];
if(temp) {
// Adding "ParenID" and "isOpen" attribute to it for(int j=0;j<[temp count];j++) {
[[[temp objectAtIndex:j] objectForKey:kRow] setObject:topicId forKey:@"ParentId"];
[[[temp objectAtIndex:j] objectForKey:kRow] setObject:[NSNumber numberWithInt:0] forKey:@"isOpen"]; } } }
else {
id agendaTopicResponse = [[EBAPIEngine sharedInstance] getMeetingAgendaTopicsWithID:topicId apiKey:mAPIKey meetingID:mMeetingID andSiteID:mSiteID];
if([agendaTopicResponse objectForKey:kRows])
temp = [agendaTopicResponse objectForKey:kRows];
if(temp) {
// Adding "ParenID" and "isOpen" attribute to it for(int j=0;j<[temp count];j++) {

//[[EBDatabaseEngine sharedInstance] insertAgendaInfoIntoTable:kAgendaTopicsTable withAgendaId:topicId withAgendaTopicID:[[[temp objectAtIndex:j] objectForKey:kRow] objectForKey:@"TopicID"] andAgendaTopicName:[[[temp objectAtIndex:j] objectForKey:kRow] objectForKey:@"TopicTitle"]];

if([mAPIKey isEqualToString:kEmptyString])
[[EBDatabaseEngine sharedInstance] insertAgendaInfoIntoTable:kAgendaTopicsTable withAgendaId:topicId withAgendaTopicID:[[[temp objectAtIndex:j] objectForKey:kRow] objectForKey:@"TopicID"] andAgendaTopicName:[[[temp objectAtIndex:j] objectForKey:kRow] objectForKey:@"TopicTitle"] andSubTopicCount:[[[temp objectAtIndex:j] objectForKey:kRow] objectForKey:@"SubTopicCount"]];

[[[temp objectAtIndex:j] objectForKey:kRow] setObject:topicId forKey:@"ParentId"];
[[[temp objectAtIndex:j] objectForKey:kRow] setObject:[NSNumber numberWithInt:0] forKey:@"isOpen"];
}
}
}
}

// If Topic doesn't Has subTopics

if(flag ==1) return;
//Checking If This perticular Row is Already Expanded or not by "isOpen" Attribute

if([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"isOpen"] isEqual:[NSNumber numberWithInt:0]])
{
int rowno = indexPath.row;
// Adding rows from Array (temp) Created From Network Called
if(flag == 2) {
for(int i =0;i<[temp count];i++)
{
[[[temp objectAtIndex:i] objectForKey:kRow] setObject:[NSNumber numberWithInt:[currentLevel intValue]+1] forKey:@"Level"]; rowno = rowno+1; [[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] setObject:[NSNumber numberWithInt:1] forKey:@"isOpen"]; NSMutableDictionary *dict1 = [[NSMutableDictionary alloc] initWithDictionary:[temp objectAtIndex:i]]; [agendaTopics insertObject:dict1 atIndex:rowno]; [mAgendaCachedArray insertObject:dict1 atIndex:no++]; [dict1 release]; } no=0; [mAgendaTableView reloadData]; if(mSelectedIndexPath) { [mSelectedIndexPath release]; mSelectedIndexPath = nil; } mSelectedIndexPath = [indexPath retain]; [mAgendaTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } // Adding rows from Array (tempArray) Created From Network Called

if(flag ==3) {
for(int i =0; i<[tempArray count]; i++)
{
[[[tempArray objectAtIndex:i] objectForKey:kRow] setObject:[NSNumber numberWithInt:[currentLevel intValue]+1] forKey:@"Level"];
rowno = rowno+1; [[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] setObject:[NSNumber numberWithInt:1] forKey:@"isOpen"];

NSMutableDictionary *dict1 = [[NSMutableDictionary alloc] initWithDictionary:[tempArray objectAtIndex:i]];
[agendaTopics insertObject:dict1 atIndex:rowno];
[dict1 release];
}

[mAgendaTableView reloadData]; if(mSelectedIndexPath) {
[mSelectedIndexPath release];
mSelectedIndexPath = nil;
}
mSelectedIndexPath = [indexPath retain];
[mAgendaTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } }

// If Row is Already Expended
else if([[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] objectForKey:@"isOpen"] isEqual:[NSNumber numberWithInt:1]])
{
m=0;
// Making a Reursive Call to find out total number of indexes that has to be deleted after current selected index
[self recurseNew:indexPath.row topic:topicId];

// Making an Index set to be deleted

NSMutableIndexSet *indexes = [NSMutableIndexSet indexSetWithIndex:indexPath.row+1];
for(int i =1; i<= m - indexPath.row - 1 ; i++) {
[indexes addIndex:indexPath.row+i+1];
}
// Msking Closed to all deleted rows in Cached Array

for(int k = indexPath.row ; k<=m ; k++) {
NSString *beClosedTopic = [[[agendaTopics objectAtIndex:k] objectForKey:kRow] objectForKey:@"TopicID"];

for(int p =0 ; p < [mAgendaCachedArray count] ; p++ )
{ if(p==0) { continue; }

if( [[[[mAgendaCachedArray objectAtIndex:p] objectForKey:kRow] objectForKey:@"TopicID"] isEqualToString:beClosedTopic])
[[[mAgendaCachedArray objectAtIndex:p] objectForKey:kRow] setObject:[NSNumber numberWithInt:0] forKey:@"isOpen"];
}
}
// Setting "isOpen" attribute as "0" means Closed

[[[agendaTopics objectAtIndex:indexPath.row] objectForKey:kRow] setObject:[NSNumber numberWithInt:0] forKey:@"isOpen"];

// Removing fetched indexes From displaying array [agendaTopics removeObjectsAtIndexes:indexes];

[mAgendaTableView reloadData]; if(mSelectedIndexPath) { [mSelectedIndexPath release]; mSelectedIndexPath = nil; } mSelectedIndexPath = [indexPath retain]; [mAgendaTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; } }


- (NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(mSelectedIndexPath != indexPath)
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
[cell setBackgroundView:nil];
[cell.textLabel setBackgroundColor:[UIColor clearColor]];
[cell.contentView setBackgroundColor:[UIColor clearColor]];
[self setNormalImageForCellAtIndexPath:indexPath andCell:cell];
}

return indexPath;
}

To get indexPath.row of tableView which is currently being displayed


NSArray *visible = [tableView indexPathsForVisibleRows];
NSIndexPath *indexpath = (NSIndexPath*)[visible objectAtIndex:0];
indexPath.row will give you index of first object displayed



2 comments:

  1. I love all the effort you put into this blog! keep it up!

    ReplyDelete
  2. i really need this code but please provide some sample code i am getting like 33 error of undeclared and redefinitions.

    ReplyDelete