Adding a row in UItableview - iphone

I am not able to add a new row in a UITableview,the code is as follows,
it showing an error with
-(void)viewDidLoad
{
self.title=#"CHECK-list";
self.navigationItem.rightBarButtonItem = self.editButtonItem;
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addItem)];
self.navigationItem.leftBarButtonItem = addButton;
ar=[[NSMutableArray alloc]initWithObjects:#"Map",#"Camera",#"First Aid Kit", nil];
[super viewDidLoad];
}
- (void)addItem
{
//NSMutableArray *tempArray = [[NSMutableArray alloc] init];
int i = 0;
for (NSArray *count in ar)
{
[ar addObject:[NSIndexPath indexPathForRow:i++ inSection:1]];
}
[[self tableView] beginUpdates];
[[self tableView] insertRowsAtIndexPaths:(NSArray *)ar withRowAnimation:UITableViewRowAnimationNone];
[[self tableView] endUpdates];
[self.tableView reloadData];
}

Here Fazil.... basic code for any tableview and the row addition
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
UITableView *tableview = [[UITableView alloc]initWithFrame:CGRectMake(160, 280, 150, 150) style:UITableViewStylePlain];
tableview.delegate = self;
tableview.dataSource = self;
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier ];
}
cell.textLabel.text= [array objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:[imagearray objectAtIndex:indexPath.row]];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"cell_normal.png"]];
cell.textLabel.textColor = [UIColor blackColor];
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:17.0];
return cell;
}
#pragma mark UItableView delegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
check = indexPath.row;
UITableViewCell* theCell = [tableView cellForRowAtIndexPath:indexPath];
theCell.contentView.backgroundColor=[UIColor clearColor];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
{
[tableview moveRowAtIndexPath:indexPath toIndexPath:[NSIndexPath indexPathForRow:[array count] - 1 inSection:1]];
}
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath
{
if (sourceIndexPath.section != proposedDestinationIndexPath.section) {
NSInteger row = 0;
if (sourceIndexPath.section < proposedDestinationIndexPath.section) {
row = [tableView numberOfRowsInSection:sourceIndexPath.section] - 1;
}
return [NSIndexPath indexPathForRow:row inSection:sourceIndexPath.section];
}
return proposedDestinationIndexPath;
}

Related

How to maintain state of selection of row in table view?

i am a beginner in xcode. I am creating a questionnaire type list with multiple rows in scroll. But when I select a row and scroll it doesn't retains its state and when I come back, it also loses its selection. So anyone please kindly let me know how to achieve that,i have tried something like this,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(val==1)
{
checkedArr=[[NSMutableArray alloc] init];
for (int i = 0; i<17; i++)
{
[checkedArr addObject:#"1"];
}
NSLog(#"Checked arr size %i",[checkedArr count]);
return 17;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%i",indexPath.row];
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil)
{
cell= [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.textLabel.numberOfLines = 0;
cell.textLabel.font = [UIFont fontWithName:#"Helvetica" size:14.0];
}
cell.textLabel.font = [UIFont fontWithName:#"Helvetica-Bold" size:18.0];
UIView *selectionColor = [[UIView alloc] init];
selectionColor.backgroundColor = [UIColor colorWithRed:99/255.0f green:209/255.0f blue:248/255.0f alpha:1.0];
cell.selectedBackgroundView = selectionColor;
if([[checkedArr objectAtIndex:indexPath.row] isEqual:#"0"])
{
cell.accessoryView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tick.png"]];
NSLog(#"checkedArr 0000000");
}
else if ([[checkedArr objectAtIndex:indexPath.row] isEqual:#"1"])
{
cell.accessoryView=nil;
NSLog(#"checkedArr 111111");
}
cell.textLabel.frame=CGRectMake(75.0, 50.0, 150.0, 20.0);
cell.textLabel.text=[listArray objectAtIndex:indexPath.row];
NSLog(#"Checked arr size %i",[checkedArr count]);
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
cell=[questionTable cellForRowAtIndexPath:indexPath];
[checkedArr replaceObjectAtIndex:indexPath.row withObject:#"0"];
if([[checkedArr objectAtIndex:indexPath.row] isEqual:#"0"])
{
cell.accessoryView=[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tick.png"]];
NSLog(#"checkedArr 0000000");
}
else if ([[checkedArr objectAtIndex:indexPath.row] isEqual:#"1"])
{[questionTable deselectRowAtIndexPath:indexPath animated:YES];
cell.accessoryView=nil;
NSLog(#"checkedArr 111111");
}
NSLog(#"Val is %i",val);
NSLog(#"selected is %#",[listArray objectAtIndex:indexPath.row]);
// NSLog(#"Checked arr descripton %#",[checkedArr description]);
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryView = UITableViewCellAccessoryNone;
}
In my application i used same code for check mark as accessoryType,check this.
take it in .h file mutable array arSelectedRows;
- (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 setSelectionStyle:UITableViewCellSelectionStyleGray];
//Do anything you want for cell here
if([arSelectedRows containsObject:indexPath]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arSelectedRows addObject:indexPath];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[arSelectedRows removeObject:indexPath];
}
NSLog(#"arSelectedRows are :%#",arSelectedRows);
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
EDIT
//if you want only single check mark
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[arSelectedRows removeAllObjects];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[arSelectedRows addObject:indexPath];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[arSelectedRows removeObject:indexPath];
}
NSLog(#"arSelectedRows are:%#",arSelectedRows);
[self.tableview reloadData];//Reload your tableview here
}
it will help you.
First your cellForRowAtIndexPath method create new cell each time whenever you scroll up/down tableView, it is very bad for memory management.
Just remove [questionTable deselectRowAtIndexPath:indexPath animated:YES] in your cellForRowAtIndexPath method
I think you need to use this api below:-
- (void)selectRowAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UITableViewScrollPosition)scrollPosition
If you are using dynamic cells, and updating your row with some kind of class variable like a NSArray, you might have set your variable to weak instead of strong.

iPhone : How can we load a custom check mark image for row in tableview?

I want to show a custom checkmark and uncheckmark image for tableview cell when user select any row and when a new row is inserted cell is loaded with uncheckmark image.
Once I check the row then even after reloading table with new data I want to display a previously checked row as it is and new as unchecked.
How can I get all rows with checked mark at end.
I tried but I am not able to load first time with custom checkmark image I can change when row is deselected but its also having some issues as it is not consistently working as I mentioned above.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [cardData.mArrRecipient count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * sCellIdentifier = #"cell";
NSLog(#"cellforrow");
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:sCellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:sCellIdentifier] autorelease];
RecipientData *recipientData = [[cardData.mArrRecipient objectAtIndex:indexPath.row]autorelease];
cell.textLabel.text = recipientData.sRecipientFName;
}
cell.accessoryType=UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (IndexPath)
{
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"img_checkmark_red.png"]] autorelease];
[tableView cellForRowAtIndexPath:indexPath].accessoryView = imageView;
IndexPath=FALSE;
}
else
{
UIImageView *imageView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"img_uncheckmark_red.png"]] autorelease];
[tableView cellForRowAtIndexPath:indexPath].accessoryView = imageView;
IndexPath=TRUE;
}
}
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([cardData.mArrRecipient count]>0)
{
[IBTblNewRecipientDetail reloadData];
}
}
can any one help me on this??
here is tutorial
http://weheartgames.com/2009/06/simple-iphone-checkbox/
or use this
UIButton * checkBox=[UIButton buttonWithType:UIButtonTypeCustom];
checkBox.tag=indexPath.row;
checkBox.frame=CGRectMake(270,15, 20, 20);
[cell.contentView addSubview:checkBox];
[checkBox setImage:[UIImage imageNamed:#"selectedBoxWith.png"] forState:UIControlStateNormal];
[checkBox addTarget:self action:#selector(checkBoxClicked:) forControlEvents:UIControlEventTouchUpInside];
-(void)checkBoxClicked:(id)sender{
if(self.isChecked ==NO){
self.isChecked =YES;
[sender setImage:[UIImage imageNamed: #"selectedBoxWithTik.png"] forState:UIControlStateNormal];
}else
{
self.isChecked =NO;
[sender setImage:[UIImage imageNamed:#"selectedBoxWith.png"]forState:UIControlStateNormal];
}
}
and
-(void)checkBoxClicked:(id)sender{
UIButton *tappedButton = (UIButton*)sender;
if([tappedButton.currentImage isEqual:[UIImage imageNamed:#"selectedBoxWith.png"]]) {
[sender setImage:[UIImage imageNamed: #"selectedBoxWithTik.png"] forState:UIControlStateNormal];
}
else {
[sender setImage:[UIImage imageNamed:#"selectedBoxWith.png"]forState:UIControlStateNormal];
}
}
For selecting multiple rows:
- (void)addTableView {
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake("whatever frame you want to set")
style:UITableViewStylePlain];
self.tableView.dataSource = self;
self.tableView.delegate = self;
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.timeSheetEntryTableView.allowsMultipleSelection = YES;
self.array = [[NSMutableArray alloc]init];
[self.view addSubview:self.tableView];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = #"Cell Identifier";
self.cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!self.cell) {
self.cell = [[Cell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
self.cell.accessoryType = UITableViewCellAccessoryNone;
}
self.cell.selectionStyle = UITableViewCellSelectionStyleNone;
if ([self.array containsObject:indexPath])
{
[self.cell.checkImage setImage:[UIImage imageNamed:#"check_box_selected.png"]];
}
else
{
[self.cell.checkImage setImage:[UIImage imageNamed:#"check_box.png"]];
}
return self.cell;
}
//did select and deselect I have used custom cell
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.cell = [tableView cellForRowAtIndexPath:indexPath];
[self.array addObject:indexPath];
[self.cell.checkImage setImage:[UIImage imageNamed:#"check_box_selected.png"]];
}
- (void)tableView:(UITableView *)tableView
didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
self.cell = [tableView cellForRowAtIndexPath:indexPath];
[self.array removeObject:indexPath];
[self.cell.checkImage setImage:[UIImage imageNamed:#"check_box.png"]];
}

UITableViewCell disorder when reloading rows to expand and shrink

I'm facing a crazy issue which is about expanding and shrinking UITableViewCell. When I click just one cell it works properly but while one cell remains open, clicking another cell to open causes the cell disorder. I would want to expand and shrink at the same time.
Here is my source.
- (void)viewDidLoad {
[super viewDidLoad];
//Initialize the array.
listOfItems = [[NSMutableArray alloc] init];
//Add items
[listOfItems addObject:#"1"];
[listOfItems addObject:#"2"];
[listOfItems addObject:#"3"];
[listOfItems addObject:#"4"];
[listOfItems addObject:#"5"];
[listOfItems addObject:#"6"];
[listOfItems addObject:#"7"];
[listOfItems addObject:#"8"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
#pragma mark Table view methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [listOfItems count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UILabel *aLabel; UILabel *bLabel; UILabel *v1Label; UILabel *v2Label;; UIView *v1; UIView *v2;
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(#" cell null");
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
aLabel = [[[UILabel alloc] initWithFrame:CGRectMake(9.0, 8.0, 50.0, 20.0)] autorelease];
aLabel.tag = 1;
aLabel.font = [UIFont systemFontOfSize:30];
[cell.contentView addSubview:aLabel];
v1 = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 116)];
v1.backgroundColor = [UIColor redColor];
v1.tag = 10;
v1.hidden = YES;
[cell.contentView addSubview:v1];
[v1 release];
v2 = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 100)];
v2.backgroundColor = [UIColor blueColor];
v2.tag = 11;
v2.hidden = YES;
[cell.contentView addSubview:v2];
[v2 release];
}
else {
aLabel = (UILabel *)[cell.contentView viewWithTag:1];
v1 = (UIView *) [cell.contentView viewWithTag:10];
v2 = (UIView *) [cell.contentView viewWithTag:11];
}
aLabel.text = [listOfItems objectAtIndex:indexPath.row];
if (SelectedIndexPath == indexPath.row)
{
if ([aLabel.text intValue] % 2) {
v1.hidden = NO;
v2.hidden = YES;
}
else {
v1.hidden = YES;
v2.hidden = NO;
}
}
else {
v1.hidden = YES;
v2.hidden = YES;
}
return cell;
}
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (SelectedIndexPath == indexPath.row)
{
return 100.0;
}
else {
return 46.0;
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (SelectedIndexPath == -1)
{
OldSelectedIndexPath = indexPath.row;
SelectedIndexPath = indexPath.row;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:NO];
}
else
{
if (SelectedIndexPath == indexPath.row)
{
OldSelectedIndexPath = SelectedIndexPath;
SelectedIndexPath = -1;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:NO];
}
else
{
SelectedIndexPath = indexPath.row;
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:[NSIndexPath indexPathForRow:OldSelectedIndexPath inSection:indexPath.section], indexPath, nil] withRowAnimation:NO];
OldSelectedIndexPath = SelectedIndexPath;
}
}
}
The problem comes from the facth that your cell will have a height of 160.0 when selected.
Look here
v1 = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 116)];
You give an heigh of 116 to a view which y origin is 44. Thus your cell view will have a total height of 160.0
Change the value returned in
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
To match the correct total height of your cell.
The problem is in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
Or may be the problem is due to releasing. anything is going to release and you are still using it.
first comment // all release and inter prate your
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

Accordion table cell - How to dynamically expand/contract uitableviewcell?

I am trying create an accordion type of uitableviewcell that, when the user selects the cell, it expands to display a detailed info view inline similar to how the digg app works. I initially tried replacing the current tablecell with a customcell in cellForRowAtIndex, however the animation looks a bit choppy as you can see the cell being replaced and overall the effect doesn't work too well.
If you look at the digg app and others who have done this it seems that they aren't replacing the current cell but instead perhaps adding a subview to the cell? The original cell however doesn't seem to animate at all and only the new view accordions into the table.
Does anyone have any ideas how to accomplish a similar effect?
I have made some progress using neha's method below and while the cell is animating the correct way it is wreaking havoc with the other cells in the table. What I have done is subclassed UITableViewCell with a custom class which contains an instance of a UIView which actually draws the view which I then add to the table cell's contentview.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
if (selected) {
[self expandCell];
}
}
-(void)expandCell {
self.contentView.frame = CGRectMake(0.0, 0.0, self.contentView.bounds.size.width, 110);
}
Here are all the table delegate methods I am using:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
static NSString *CellIdentifier = #"SearchCell";
CustomTableCell *cell = (CustomTableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
UILabel *theText = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 10.0, cell.contentView.bounds.size.width -20, 22.0)];
theText.text = #"Title Text";
[cell.contentView addSubview:theText];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 10 + 46.0, cell.contentView.bounds.size.width - 20, 40.0)];
textField.borderStyle = UITextBorderStyleLine;
[cell.contentView addSubview:textField];
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 88.0, cell.contentView.bounds.size.width - 20, 22.0)];
testLabel.text = [NSString stringWithFormat:#"Some text here"];
[cell.contentView addSubview:testLabel];
[theText release];
[textField release];
[testLabel release];
return cell;
} else {
static NSString *CellIdentifier = #"Cell";
CustomTableCell *cell = (CustomTableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
selectedIndex = indexPath.row;
isSearching = YES;
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
return 110;
}
return rowHeight;
}
It seems now that the cell is expanding but not actually being refreshed so the labels, and textfield aren't being shown. They do however show up when I scroll the cell off and on the screen.
Any ideas?
The Apple way to do is quite simple.
First, you'll need to save the selected indexPath row:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedRowIndex = [indexPath retain];
[tableView beginUpdates];
[tableView endUpdates];
}
I'll explain the begin/end updated part later.
Then, when you have the currently selected index, you can tell the tableView that it should give that row more space.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//check if the index actually exists
if(selectedRowIndex && indexPath.row == selectedRowIndex.row) {
return 100;
}
return 44;
}
This will return height 100 for the selected cell.
Now we can go back to the begin/end updates. That block triggers the reload of all tableView geometry. Moreover, that block is animated, which eventually gives the impressions of the row expanding.
Pawel's beginUpdates/endUpdates trick is good, and I often use it. But in this case you simply need to reload the rows that are changing state, ensuring that you correctly reload them with the desired cell type, and that you return the correct new cell height.
Here is a complete working implementation of what I think you're trying to accomplish:
.h:
#import <UIKit/UIKit.h>
#interface ExpandingTableViewController : UITableViewController
{
}
#property (retain) NSIndexPath* selectedIndexPath;
#end
.m:
#implementation ExpandingTableViewController
#synthesize selectedIndexPath;
- (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 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier1 = #"Cell1";
static NSString *CellIdentifier2 = #"Cell2";
UITableViewCell *cell;
NSIndexPath* indexPathSelected = self.selectedIndexPath;
if ( nil == indexPathSelected || [indexPathSelected compare: indexPath] != NSOrderedSame )
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat: #"cell %d", indexPath.row];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier2] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat: #"cell %d", indexPath.row];
cell.detailTextLabel.text = [NSString stringWithFormat: #"(expanded!)", indexPath.row];
}
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( self.selectedIndexPath != nil && [self.selectedIndexPath compare: indexPath] == NSOrderedSame )
{
return tableView.rowHeight * 2;
}
return tableView.rowHeight;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray* toReload = [NSArray arrayWithObjects: indexPath, self.selectedIndexPath, nil];
self.selectedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths: toReload withRowAnimation: UITableViewRowAnimationMiddle];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
#end
If you don't want to reload the cell (you want to keep your existing cell and just change the size, and likely add/remove some subviews), then simply do the beginUpdates/endUpdates trick in didSelectRowAtIndexPath:, and call some method on your cell to incite the layout change. beginUpdates/endUpdates will prompt the tableView to re-query the heights for each cell - so be sure to return the correct value.
Create a class that subclasses UITableviewcell in your project. Create this class' nib and set its parent to be the class in your project with tableview and override its -
(void)setSelected:(BOOL)selected animated:(BOOL)animated
Write methods contractCell() and expandCell() in this class, and provide the height of the cells you want in expandCell method. Call this methods appropriately based on some flags set to identify wheather the cell is in expanded state or contracted state. Use your tableview's
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
method to handle selection of cells.
Replace your cellForRowAtIndexPath function with this one.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
static NSString *CellIdentifier = #"SearchCell";
CustomTableCell *cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
UILabel *theText = [[UILabel alloc] initWithFrame:CGRectMake(10.0,
10.0, cell.contentView.bounds.size.width
-20, 22.0)];
theText.text = #"Title Text";
[cell.contentView addSubview:theText];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 10 +
46.0, cell.contentView.bounds.size.width - 20, 40.0)];
textField.borderStyle = UITextBorderStyleLine;
[cell.contentView addSubview:textField];
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0,
88.0, cell.contentView.bounds.size.width - 20, 22.0)];
testLabel.text = [NSString stringWithFormat:#"Some text here"];
[cell.contentView addSubview:testLabel];
[theText release];
[textField release];
[testLabel release];
return cell;
} else {
static NSString *CellIdentifier = #"Cell";
CustomTableCell *cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
return cell;
}
}
create array wof dictionary which have a key Select_sts which is 0 in start when click its change 1
accourding u change table
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
customView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 40.0)];
UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.opaque = NO;
headerLabel.textColor = [UIColor blackColor];
headerLabel.highlightedTextColor = [UIColor whiteColor];
headerLabel.font = [UIFont boldSystemFontOfSize:16];
headerLabel.frame = CGRectMake(5.0, 10.0, 300.0, 20.0);
headerLabel.text=[NSString stringWithFormat: #"PNR %#",[[record objectAtIndex:section] objectForKey:#"number"]];
customView.backgroundColor=[UIColor whiteColor];
btn_openClose.tag=section+10000;
btn_openClose.backgroundColor=[UIColor clearColor];
// [btn_openClose setImage:[UIImage imageNamed:#"down_arrow.png"] forState:UIControlStateNormal];
[btn_openClose addTarget:self action:#selector(collapseExpandButtonTap:) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:btn_openClose];
}
- (void) collapseExpandButtonTap:(id) sender{
int indexNo=[sender tag]-10000;
// NSLog(#"total_record %#",[total_record objectAtIndex:indexNo]);
NSMutableDictionary *mutDictionary = [[total_record objectAtIndex:indexNo] mutableCopy];
if([[mutDictionary objectForKey:#"Select_sts"] integerValue]==0)
[mutDictionary setObject:[NSNumber numberWithInt:1] forKey:#"√"];
else
[mutDictionary setObject:[NSNumber numberWithInt:0] forKey:#"Select_sts"];
[total_record replaceObjectAtIndex:indexNo withObject:mutDictionary];
// [table_view beginUpdates];
// [table_view reloadData];
// [table_view endUpdates];
NSMutableIndexSet *indetsetToUpdate = [[NSMutableIndexSet alloc]init];
[indetsetToUpdate addIndex:indexNo]; // [indetsetToUpdate addIndex:<#(NSUInteger)#>]
// You can add multiple indexes(sections) here.
[table_view reloadSections:indetsetToUpdate withRowAnimation:UITableViewRowAnimationFade];
}

How can you push a new view with a grouped table?

Ive been trying to push a new view when a cell is tapped but absolutely nothing happens. I figured grouped style pushed the same as plain. Here is my code:
-(void)viewDidLoad {
[super viewDidLoad];
contactArray = [[NSArray alloc] initWithObjects:#"iPhone",#"iPod",#"MacBook",#"MacBook Pro",nil];
shareArray = [[NSArray alloc] initWithObjects:#"Flex",#"AIR",#"PhotoShop",#"Flash",nil];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
// Customize the number of rows in the table view.
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section == 0)
return [contactArray count];
else
return [shareArray count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if(section == 0){
return #"Contact";
}else{
return #"Share";
}
}
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section{
if(section == 0){
return #"Footer for Apple Products";
}else{
return #"Footer for Adobe Softwares";
}
}
// Customize the appearance of table view cells.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
if(indexPath.section == 0){
cell.text = [contactArray objectAtIndex:indexPath.row];
}else{
cell.text = [shareArray objectAtIndex:indexPath.row];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//NextViewController *nextController = [[NextViewController alloc] initWithNibName:#"NextView" bundle:nil];
//[self.navigationController pushViewController:nextController animated:YES];
if([contactArray objectAtIndex:indexPath.row] == #"iPhone"){
LandscapeHydrogen *abo = [[LandscapeHydrogen alloc] initWithNibName:#"LandscapeHydrogen" bundle:nil];
[self.navigationController pushViewController:abo animated:NO];
[abo release];
}
}
Any help is appreciated.
You could put a breakpoint at the didSelectRowAtIndexPath to see if the if statement is true.
Try changing
if([contactArray objectAtIndex:indexPath.row] == #"iPhone"){
to
if([[contactArray objectAtIndex:indexPath.row] isEqualToString:#"iPhone"]){
YourNextViewController * nextViewController = [[YourNextViewController alloc] initWithNibName: #"YourNextViewController" bundle: nil];
switch (indexPath.section) {
case 0:
nextViewController.title = [_contactArray objectAtIndex: [indexPath row]];
break;
case 1:
nextViewController.title = [_shareArray objectAtIndex: [indexPath row]];
break;
default:
break;
}
[[self navigationController] pushViewController:nextViewController animated:YES];
}
Solved with
else if (indexPath.section == 1 & indexPath.row == 0){
FaceBook *nextController = [[FaceBook alloc] initWithNibName:#"FaceBook" bundle:nil];
[self.navigationController pushViewController:nextController animated:YES];