I'm trying to realize a UITableViewController with 7 sections. Each sections has a number of rows that could change by user events. For istance, in the first section I have a single row with a UISwitch: if the user activates the switch, 2 more rows appear in that section. The same for section 2. Ok for now....
In sections 3,4,5 I also have a single row (Value1 Cell, iPhone general settings like): by pressing on that cell, the sections shows on the 2nd row a UISegmented control with 3 segments. By pressing one of that segments, the user make his choice and the segmented control row disappears, the sections has a single row again with the value choosed as detailTextLabel.
Well, all these procedures are managed with a reloadSections method that reloads the sections in with the user is interacting. My code is below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [ tableView dequeueReusableCellWithIdentifier: CellIdentifier];
CellIdentifier = [ NSString stringWithFormat: #"%d:%d", [ indexPath indexAtPosition: 0 ], [ indexPath indexAtPosition:1 ]];
//cell = nil;
if(indexPath.section == 0 && [indexPath indexAtPosition: 1] == 0)
{
CellIdentifier = #"test";
}
if (cell == nil) {
cell = [ [ [ UITableViewCell alloc ] initWithFrame: CGRectZero reuseIdentifier: CellIdentifier] autorelease ];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
switch ([ indexPath indexAtPosition: 0]) {
case(0): {
switch([ indexPath indexAtPosition: 1]) {
case(0):
{
positionControl.tag = 0;
[positionControl addTarget:self action:#selector(toggleSwitch:) forControlEvents:UIControlEventValueChanged];
[ cell addSubview: positionControl ];
cell.textLabel.text = NSLocalizedString(#"Position",#"");
}
break;
case(1):
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text = NSLocalizedString(#"Some Position",#"");
cell.detailTextLabel.text = NSLocalizedString(#"Last Known Position",#"");
}
break;
case(2):
{
cell.textLabel.text = NSLocalizedString(#"ReDo Position",#"");
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
break;
}
}
break;
case(1): {
switch ([ indexPath indexAtPosition: 1 ]) {
case(0):
{
photoControl.tag = 1;
[photoControl addTarget:self action:#selector(toggleSwitch:) forControlEvents:UIControlEventValueChanged];
[ cell addSubview: photoControl ];
cell.textLabel.text = NSLocalizedString(#"photos",#"");
}
break;
case(1):
{
cell.textLabel.text = NSLocalizedString(#"Take photo",#"");
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
break;
case(2):
{
cell.textLabel.text = NSLocalizedString(#"Select from Roll",#"");
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
break;
}
}
break;
case(2): {
switch ([ indexPath indexAtPosition: 1 ]) {
case(0):
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text = NSLocalizedString(#"size",#"");
if (UISegmentedControlNoSegment != [dimensionSegmentedControl selectedSegmentIndex]) {
cell.detailTextLabel.text = [dimensionSegmentedControl titleForSegmentAtIndex:[dimensionSegmentedControl selectedSegmentIndex]];
}
else {
cell.detailTextLabel.text = NSLocalizedString(#"Select",#"");
}
}
break;
case(1):
{
[dimensionSegmentedControl addTarget:self action:#selector(onSegmentedControlChanged:) forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:dimensionSegmentedControl];
}
break;
}
}
break; ...
Then my Action for switches:
- (IBAction) toggleSwitch: (id) sender {
UISwitch *switchControl = (UISwitch *) sender;
NSUInteger tag = switchControl.tag;
NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:tag];
[self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
[sectionsToReload release];}
Action for segmentedcontrol
- (IBAction) onSegmentedControlChanged: (id) sender {
UISegmentedControl *segmentedControl = (UISegmentedControl *) sender;
NSUInteger tag = segmentedControl.tag;
NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:tag];
segmentedControl.momentary = YES;
[self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
segmentedControl.momentary = NO;
[sectionsToReload release];}
This is the didSelectRow
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
switch ([ indexPath indexAtPosition: 0]) {
case(2): {
switch([ indexPath indexAtPosition: 1]) {
case (0): {
if (UISegmentedControlNoSegment != [dimensionSegmentedControl selectedSegmentIndex]) {
dimensionSegmentedControl.selectedSegmentIndex = [dimensionSegmentedControl selectedSegmentIndex];
}
else {
dimensionSegmentedControl.selectedSegmentIndex = 0;
}
NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:2];
//[self.tableView reloadData];
[self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[sectionsToReload release];
}
break;
}
}
break;
case(3): {
switch([ indexPath indexAtPosition: 1]) {
case (0): {
if (UISegmentedControlNoSegment != [patientsSegmentedControl selectedSegmentIndex]) {
patientsSegmentedControl.selectedSegmentIndex = [patientsSegmentedControl selectedSegmentIndex];
}
else {
patientsSegmentedControl.selectedSegmentIndex = 0;
}
NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:3];
//[self.tableView reloadData];
[self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[sectionsToReload release];
}
break;
default:
break;
}
}
break;
case(4): {
switch([ indexPath indexAtPosition: 1]) {
case (0): {
if (UISegmentedControlNoSegment != [patientsStateSegmentedControl selectedSegmentIndex]) {
patientsStateSegmentedControl.selectedSegmentIndex = [patientsStateSegmentedControl selectedSegmentIndex];
}
else {
patientsStateSegmentedControl.selectedSegmentIndex = 0;
}
NSIndexSet *sectionsToReload = [[NSIndexSet alloc] initWithIndex:4];
//[self.tableView reloadData];
[self.tableView reloadSections:sectionsToReload withRowAnimation:NO];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[sectionsToReload release];
}
break;
}
}
break;
case(5): {
switch([ indexPath indexAtPosition: 1]) {
case (0):
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel://4030"]];
break;
case (1):
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"tel://4030"]];
break;
}
}
break;
default: break;
}}
And finally my numbersOfRowsInSections, probably the problems source:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
switch (section) {
case (0):
{
if (!positionControl.on) {
return 1;
break;
}
return 3;
}
break;
case (1):
{
if (!photoControl.on) {
return 1;
break;
}
return 3;
}
break;
case (2):
{
if (UISegmentedControlNoSegment == [dimensionSegmentedControl selectedSegmentIndex] || [dimensionSegmentedControl isMomentary]) {
return 1;
break;
}
return 2;
}
break;
case (3):
{
if (UISegmentedControlNoSegment == [patientsSegmentedControl selectedSegmentIndex] || [patientsSegmentedControl isMomentary]) {
return 1;
break;
}
return 2;
}
break;
case (4):
{
if (UISegmentedControlNoSegment == [patientsStateSegmentedControl selectedSegmentIndex] || [patientsStateSegmentedControl isMomentary]) {
return 1;
break;
}
return 2;
}
break;
case (5): {
return 2;
}
break;
case (6): {
return 1;
}
break;
}
return 0;}
Well, now you can see my code, I'll explain my problem. When I deal with UISwitches, the sections reload properly....rows appear and disappear in the first two sections like a charm. But, when I click on the cells from sections with segmented controls, the first time everything is ok, the cell shows the segmented control, the user makes his choice, the segmented control disappears and the single row shows the user choice in the detailTextLabel.But when I try to click on another row, the app crashes with this exception:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 3. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted).'
2010-07-16 13:09:04.595 Barcodes[40421:207] Stack: (
35943515,
2535093513,
36027451,
1928964,
4228395,
4172781,
278302,
4188742,
4171908,
1425834,
35728064,
35724360,
43226645,
43226842,
3915695,
86847,
86454
)
Difference between two sections is that ones with UISwitches show and hide rows by activating/deactivating the switch, others by selecting rows (didSelectRow....).
ANY HELP??
Thank you in advance.
my code is good if I simply add a flag (BOOL) saying is each segmented control must be visible or not. Setting on "YES" and "NO" these flags and checking their value everything works properly.
Related
Trying to expand the sections in UITableview. Everything is working fine but if the expanded section is not closed and the view is popup and then push to that view again where tableview is, the section expanded last time gets disappear and if any section in tableview selected the app crashes. I checked through breakpoint the issue is next time it starts with section1 not from section0. Why this is happening i am not getting. Below is the code i am using.
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.arrList count];
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0)
{
if(indexSectionOne)
{
return [self.arrProductsList count];
}
else
{
return 1;
}
}
if(section == 1)
{
if(indexSectionTwo)
{
return [self.arrServicesList count];
}
else
{
return 1;
}
}
else
return 1;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"CellIdentifier";
AboutCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell==nil)
{
cell = [[AboutCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
}
/*
if((indexPath.section == 0)||(indexPath.section == 1))
{
if(indexPath.row == 0)
{
cell.imgDwnView.image = [UIImage imageNamed:#"down_arrow_about_iPhone.png"];
}
}
*/
NSLog(#"row:%d section:%d", indexPath.row, indexPath.section);
if(indexPath.section == 0)
{
if(indexPath.row == 0)
{
NSLog(#"row:%d section:%d", indexPath.row, indexPath.section);
cell.imgDwnView.image = [UIImage imageNamed:#"down_arrow_about_iPhone.png"];
}
//if(indexPath.row != 0)
else
{
NSLog(#"row:%d section:%d", indexPath.row, indexPath.section);
cell.imgView.image = [UIImage imageNamed:[self.arrImages objectAtIndex:0]];
cell.lblView.text = [[self.arrProductsList objectAtIndex:indexPath.row-1] valueForKey:#"ProductName"];
cell.txtView.text = [[self.arrProductsList objectAtIndex:indexPath.row-1] valueForKey:#"ProductDescription"];
}
}
if(indexPath.section == 1)
{
if(indexPath.row == 0)
{
NSLog(#"row:%d section:%d", indexPath.row, indexPath.section);
cell.imgDwnView.image = [UIImage imageNamed:#"down_arrow_about_iPhone.png"];
}
//if(indexPath.row != 0)
else
{
NSLog(#"row:%d section:%d", indexPath.row, indexPath.section);
cell.imgView.image = [UIImage imageNamed:[self.arrImages objectAtIndex:1]];
cell.lblView.text = [[self.arrServicesList objectAtIndex:indexPath.row-1] valueForKey:#"LinkTitle"];
cell.txtView.text = [[self.arrServicesList objectAtIndex:indexPath.row-1] valueForKey:#"ProductDescription"];
}
}
if(indexPath.row == 0)
{
NSLog(#"row:%d section:%d", indexPath.row, indexPath.section);
cell.contentView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"cell_background_about_iPhone.png"]];
cell.lblView.text = [self.arrList objectAtIndex:indexPath.section];
cell.imgView.image = [UIImage imageNamed:[self.arrImages objectAtIndex:indexPath.section]];
cell.lblView.font = [UIFont fontWithName:#"NeoSansCyr-Regular" size:15.0f];
cell.lblView.textColor = [UIColor colorWithRed:144.0/255.0 green:8.0/255.0 blue:8.0/255.0 alpha:1.0];
}
else
{
NSLog(#"row:%d section:%d", indexPath.row, indexPath.section);
cell.lblView.frame = CGRectMake(60, 15, 150, 25);
cell.imgView.frame = CGRectMake(13, 15, 30, 30);
cell.txtView.frame = CGRectMake(60, 42, 180, 50);
cell.imgDwnView.frame = CGRectMake(270, 18, 19, 10);
cell.imgDwnView.image = [UIImage imageNamed:#"down_arrow_about_iPhone.png"];
//cell.lblView.text = #"Labels";
// cell.imgView.image = [UIImage imageNamed:#"Icon-small.jpg"];
// cell.txtView.text = #"Description";
cell.contentView.backgroundColor = [UIColor whiteColor];
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.section == 0)
{
indexSectionOne = !indexSectionOne;
if(indexSectionOne)
{
}
else
{
}
[self.tblAboutView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
}
if(indexPath.section == 1)
{
indexSectionTwo = !indexSectionTwo;
if(indexSectionTwo)
{
}
else
{
}
[self.tblAboutView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
}
if(indexPath.section == 2)
{
MapViewController *mapView = [[MapViewController alloc]initWithNibName:#"MapViewController" bundle:nil];
mapView.strTitle = #"Branches/ATM";
[self.navigationController pushViewController:mapView animated:YES];
}
if(indexPath.section == 3)
{
MapViewController *mapView = [[MapViewController alloc]initWithNibName:#"MapViewController" bundle:nil];
mapView.strTitle = #"Sadara Centre";
[self.navigationController pushViewController:mapView animated:YES];
}
if(indexPath.section == 4)
{
NSString *strRoadAsstNo = [dictData valueForKey:#"RoadSideAssistanceNo"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:strRoadAsstNo]];
}
if(indexPath.section == 5)
{
NSString *strContactNo = [dictData valueForKey:#"ContactCenterNo"];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:strContactNo]];
}
}
Update:
Error: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (33) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
Thanks in advance. Please guide for above where i am doing wrong.
Spent hours and hours and no use.I don't understand whether I was not effective in searching(googling) or is it that there are less questions on this or I might have committed some mistake while implementing the answers of experts!
I know there are several questions on setting accessory type check mark for one row and none for other rows in a section,traced out posts here and there.
I have 2 sections in my table view.By default I want the 1st row in each section to be selected i.e. with accessory view check mark.Now from here upon user selection of a row,I want the check mark to be visible on selected row only.I have tried declaring two index paths to keep track of row selection in each section.Here is my implementation code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.row,indexPath.section];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (indexPath.section == 0)
{
if(self.firstSectionIndex == indexPath)
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
if (indexPath.section == 1)
{
if(self.secondSectionIndex == indexPath)
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
switch (indexPath.section)
{
case 0:
{
if (indexPath.row == 0)
{
if(self.firstSectionIndex != indexPath)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = #"Yes";
}
if (indexPath.row == 1)
{
cell.textLabel.text = #"No";
}
}
break;
case 1:
{
if (indexPath.row == 0)
{
if(self.secondSectionIndex != indexPath)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.textLabel.text = #"Easy";
}
if (indexPath.row == 1)
{
cell.textLabel.text = #"Medium";
}
if (indexPath.row == 2)
{
cell.textLabel.text = #"Hard";
}
}
break;
default:
break;
}
}
tableView.backgroundColor = [UIColor clearColor];
tableView.backgroundView = nil;
return cell;
}
in my didSelectRowAtIndexPath,I have done the following:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
self.firstSectionIndex = indexPath;
}
if (indexPath.section == 1)
{
self.secondSectionIndex = indexPath;
}
[tableView reloadData];
}
I have searched for the state of cell selection to be saved for long term reference,in quest of it,I found some useful link here.
But it is selecting multiple cells and accessory type check mark is being applied for all rows in section.I don't understand what's wrong.Can any one please guide me on this!!
Thanks all in advance :)
you can achieve it using this bellow implementation of code :-
EDITED
.h file
NSMutableArray *firstSelectedCellsArray;
NSMutableArray *secondSelectedCellsArray;
NSMutableArray *ThirdSelectedCellsArray;
in .m file
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0)
{
NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
{
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
if ( [firstSelectedCellsArray containsObject:rowNumber] )
{
[firstSelectedCellsArray removeObject:rowNumber];
}
else
{
[firstSelectedCellsArray addObject:rowNumber];
}
}
else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
{
if ( [firstSelectedCellsArray containsObject:rowNumber] )
{
[firstSelectedCellsArray removeObject:rowNumber];
}
else
{
[firstSelectedCellsArray addObject:rowNumber];
}
selectedCell.accessoryType = UITableViewCellAccessoryNone;
}
}
if (indexPath.section == 1)
{
NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
{
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
if ( [secondSelectedCellsArray containsObject:rowNumber] )
{
[secondSelectedCellsArray removeObject:rowNumber];
}
else
{
[secondSelectedCellsArray addObject:rowNumber];
}
}
else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
{
if ( [secondSelectedCellsArray containsObject:rowNumber] )
{
[secondSelectedCellsArray removeObject:rowNumber];
}
else
{
[secondSelectedCellsArray addObject:rowNumber];
}
selectedCell.accessoryType = UITableViewCellAccessoryNone;
}
}
if (indexPath.section == 2)
{
NSNumber *rowNumber = [NSNumber numberWithUnsignedInt:indexPath.row];
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if (selectedCell.accessoryType == UITableViewCellAccessoryNone)
{
selectedCell.accessoryType = UITableViewCellAccessoryCheckmark;
if ( [ThirdSelectedCellsArray containsObject:rowNumber] )
{
[ThirdSelectedCellsArray removeObject:rowNumber];
}
else
{
[ThirdSelectedCellsArray addObject:rowNumber];
}
}
else if (selectedCell.accessoryType == UITableViewCellAccessoryCheckmark)
{
if ( [ThirdSelectedCellsArray containsObject:rowNumber] )
{
[ThirdSelectedCellsArray removeObject:rowNumber];
}
else
{
[ThirdSelectedCellsArray addObject:rowNumber];
}
selectedCell.accessoryType = UITableViewCellAccessoryNone;
}
}
}
NOW in cellForRowAtIndexPath put littel piece of code:-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
if(indexPath.section==0)
{
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
if ( [firstSelectedCellsArray containsObject:rowNsNum] )
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
if(indexPath.section==1)
{
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
if ( [secondSelectedCellsArray containsObject:rowNsNum] )
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
if(indexPath.section==2)
{
NSNumber *rowNsNum = [NSNumber numberWithUnsignedInt:indexPath.row];
if ( [ThirdSelectedCellsArray containsObject:rowNsNum] )
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
}
return cell;
}
DEMO LINK
http://www.sendspace.com/file/z6oxg2
ScreenShot:
I have found a precise and perfect solution,thanks to Lithu T.V and Nithin Gobel for guiding me in the right direction.Unfortunately their solutions didn't help me in achieving 1 check mark per section,but multiple check marks in fact.So I thought of saving the selected row in user defaults and for initially selecting 1st row of each section,we declare first and second section index,assign to index path and then assign cell accessory view as check mark.Here we go,let's first deal with cellForRowAtIndexPath:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.row,indexPath.section];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
cell.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor whiteColor];
NSUserDefaults *savedState = [NSUserDefaults standardUserDefaults];
switch (indexPath.section)
{
case 0:
{
NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
if([[savedState objectForKey:#"firstSectionIndex"] isEqual: indexNumber])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.firstSectionIndex = indexPath;
}
if (indexPath.row == 0)
{
NSObject * checkedCellObject = [savedState objectForKey:#"firstSectionIndex"];
if(checkedCellObject == nil)
{
self.firstSectionIndex = indexPath;
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
cell.textLabel.text = #"Yes";
}
if (indexPath.row == 1)
{
cell.textLabel.text = #"No";
}
}
break;
case 1:
{
NSNumber *indexNumber = [NSNumber numberWithInteger:indexPath.row];
if([[savedState objectForKey:#"secondSectionIndex"] isEqual: indexNumber])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
secondSectionIndex = indexPath;
}
if (indexPath.row == 0)
{
NSObject * checkedCellObject = [savedState objectForKey:#"secondSectionIndex"];
if(checkedCellObject == nil)
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
secondSectionIndex = indexPath;
}
cell.textLabel.text = #"Easy";
}
if (indexPath.row == 1)
{
cell.textLabel.text = #"Medium";
}
if (indexPath.row == 2)
{
cell.textLabel.text = #"Hard";
}
}
break;
default:
break;
}
}
tableView.backgroundColor = [UIColor clearColor];
tableView.backgroundView = nil;
return cell;
}
Please observe in each case,we are checking if the checked state is in saved user defaults,if it is nil,we check 1st cell(row) of each section,here we go with table view delegate method,did select row at index path:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.section == 0)
{
UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
if(firstSectionIndex && firstSectionIndex != indexPath)
{
UITableViewCell *uncheckCell = [tableView cellForRowAtIndexPath:firstSectionIndex];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
self.firstSectionIndex = indexPath;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:firstSectionIndex.row] forKey:#"firstSectionIndex"];
checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
if (indexPath.section == 1)
{
UITableViewCell *checkCell = [tableView cellForRowAtIndexPath:indexPath];
if(secondSectionIndex)
{
UITableViewCell *unchekCell = [tableView cellForRowAtIndexPath:secondSectionIndex];
unchekCell.accessoryType = UITableViewCellAccessoryNone;
}
self.secondSectionIndex = indexPath;
[[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInt:secondSectionIndex.row] forKey:#"secondSectionIndex"];
checkCell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
That's it,we have successfully accomplished one check mark per section and also save the accessory state of cell in user defaults for long term reference.
Hope this helps some one,thanks :)
for implementing checkmark
Keep an index array for selected indexes
In the cellFor Row method check if current indexpath is there in the
selected index array.
if true
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
In didSelect method if checkmarked.Remove index from array as well
as set the accessory type none
If accessory none add the checkmark and add the index into array .
EDIT
In case what you need is the single selection everytime you select a cell remove all index from array and add that only and then reload tableview
I have the similar requirement where I need to select a single option per section and show the tick mark and I have achieved the same with simple steps. You do not need to reload the section or table at all.
Step 1:
Keep a hash-table/dictionary to your model which keeps the record of selected IndexPath per section type.
Example -
class DeviceSettingModel {
var indexPathSelectionDict: [DeviceSettingSectionType: IndexPath] = [:]
}
enum DeviceSettingSectionType: Int {
case audioDevices
case videoDevices
case videoQualities
}
Step 2:
Update the selection in tableView(didSelectAtRow) delegate:
Example -
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
guard let settingModel = settingModel,
let type: DeviceSettingSectionType = DeviceSettingSectionType(rawValue: indexPath.section)
else { return }
// other data and view related updating...
// unselect first on the same section.
if let previousIndex = settingModel.indexPathSelectionDict[type] {
if let cell = tableView.cellForRow(at: previousIndex) {
cell.accessoryType = .none
}
}
// update selected indexPath into the model and put a tick mark
settingModel.indexPathSelectionDict[type] = indexPath
if let cell = tableView.cellForRow(at: indexPath) {
cell.accessoryType = .checkmark
}
}
That's it, you can see below effect.
Please take a look at the image.
I have a UITableView with custom cells and 2 sections. Once the UITableView populates enough cells that they all can't be shown on the screen, the last cell in the last section appears at the very top of the screen. The cell shouldn't even be visible in the UITableView since it's the last cell, and it is appearing completely outside the UITableView, at the top of the screen. I'm at a loss for even knowing where to begin to look in my code for this issue. I've only created a couple of UITableViews so I'm definitely not an expert on all the potential causes for this bug. The Table is set up through IB and the initialization code is in viewWillAppear, although there isn't much set up code. I am currently reading up on UITableView's scrollView, along with contentInset to see if there might be an explanation for this behavior. Has anyone encountered such a bug? I feel like it's unique enough that it may not be necessary to comb through all my code to determine. Regardless, I will post the relevant code below. Thank you for your help!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *uniqueIdentifierForPlayerCell = #"customPlayerCell";
//Initialize PlayerTableViewCell and set it's properties
PlayerTableViewCell *playerCell = nil;
playerCell = (PlayerTableViewCell *)[tableView dequeueReusableCellWithIdentifier:uniqueIdentifierForPlayerCell];
if (playerCell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"PlayerTableViewCell" owner:nil options:nil];
for(id currentObject in topLevelObjects) {
if([currentObject isKindOfClass:[PlayerTableViewCell class]]) {
playerCell = (PlayerTableViewCell *)currentObject;
break;
}
}
}
playerCell.textLabel.opaque = NO;
playerCell.textLabel.textColor = self.textColor;
playerCell.textLabel.font = [UIFont systemFontOfSize:18.0];
playerCell.textLabel.backgroundColor = [UIColor clearColor];
playerCell.selectionStyle = UITableViewCellSelectionStyleNone;
playerCell.accessoryButton.hidden = YES;
playerCell.reorderButton.hidden = YES;
NSString *uniqueIdentifierForAlleyCell = #"customAlleyCell";
//Initialize AlleyTableViewcell and set it's properties
AlleyTableViewCell *alleyCell = nil;
alleyCell = (AlleyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:uniqueIdentifierForAlleyCell];
if (alleyCell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"AlleyTableViewCell" owner:nil options:nil];
for(id currentObject in topLevelObjects) {
if([currentObject isKindOfClass:[AlleyTableViewCell class]]) {
alleyCell = (AlleyTableViewCell *)currentObject;
break;
}
}
}
alleyCell.textLabel.opaque = NO;
alleyCell.textLabel.textColor = self.textColor;
alleyCell.textLabel.font = [UIFont systemFontOfSize:18.0];
alleyCell.textLabel.backgroundColor = [UIColor clearColor];
alleyCell.selectionStyle = UITableViewCellSelectionStyleNone;
alleyCell.accessoryButton.hidden = YES;
alleyCell.deleteButton.hidden = YES;
//Alternate background colors for each section where section 0 is Alley section and section 1 is Player section. Stores the RGB values of the specific background color to the specific cell for future use
if(indexPath.section == 0 && (indexPath.row %2 == 0)) {
alleyCell.contentView.backgroundColor = self.backgroundColor;
alleyCell.isRed = 95.0/255.0;
alleyCell.isGreen = 94.0/255.0;
alleyCell.isBlue = 94.0/255.0;
self.alleyField.backgroundColor = self.backgroundColor;
}
else if(indexPath.section == 0 && (indexPath.row %2 == 1)){
alleyCell.contentView.backgroundColor = self.alternateColor;
alleyCell.isRed = 92.0/255.0;
alleyCell.isGreen = 92.0/255.0;
alleyCell.isBlue = 92.0/255.0;
self.alleyField.backgroundColor = self.alternateColor;
}
else if(indexPath.section == 1 && (indexPath.row %2 == 0)) {
playerCell.contentView.backgroundColor = self.backgroundColor;
playerCell.isRed = 95.0/255.0;
playerCell.isGreen = 94.0/255.0;
playerCell.isBlue = 94.0/255.0;
self.playerField.backgroundColor = self.backgroundColor;
}
else if(indexPath.section == 1 && (indexPath.row %2 == 1)) {
playerCell.contentView.backgroundColor = self.alternateColor;
playerCell.isRed = 92.0/255.0;
playerCell.isGreen = 92.0/255.0;
playerCell.isBlue = 92.0/255.0;
self.playerField.backgroundColor = self.alternateColor;
}
//If Alley array is empty, add alley TextField and return cell
if(indexPath.section == 0) {
if([self.allAlleys count] == 0) {
[alleyCell addSubview:self.alleyField];
self.alleyField.text = nil;
return alleyCell;
}
//Else set the alley name to the nameLabel text and return cell
else {
if(indexPath.row < [self.allAlleys count]) {
alleyCell.textLabel.text = [self.allAlleys objectAtIndex:indexPath.row];
if([alleyCell.textLabel.text isEqualToString: self.selectedAlley]) {
alleyCell.accessoryButton.hidden = NO;
}
else {
alleyCell.accessoryButton.hidden = YES;
}
return alleyCell;
}
//Add alley TextField to the last cell of the UITableView and return cell
else {
[alleyCell addSubview:self.alleyField];
self.alleyField.text = nil;
return alleyCell;
}
}
}
//If Player array is empty, add Player TextField and return cell
else if(indexPath.section == 1) {
if([self.bowlrNames count] == 0) {
[playerCell addSubview:self.playerField];
self.playerField.text = nil;
return playerCell;
}
//Else set the Player name to the nameLabel text and return cell
else {
if(indexPath.row < [self.bowlrNames count]) {
playerCell.textLabel.text = [self.bowlrNames objectAtIndex:indexPath.row];
for(int i = 0; i < [self.selectedBowlrs count]; i++) {
if([playerCell.textLabel.text isEqualToString: [self.selectedBowlrs objectAtIndex:i]]) {
playerCell.accessoryButton.hidden = NO;
playerCell.reorderButton.hidden = NO;
}
}
return playerCell;
}
//Add Player textField to the last cell of the UITableView and return cell
else {
[playerCell addSubview:self.playerField];
self.playerField.text = nil;
return playerCell;
}
}
}
}
//Actions for selecting a row in the UITable
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
//If it is in the Alley section
if(indexPath.section == 0) {
//If the selected cell is the same as the last selected cell
if(self.lastIndexPathForAlleyCells && indexPath.row == self.lastIndexPathForAlleyCells.row) {
[tableView beginUpdates];
self.lastIndexPathForAlleyCells = nil;
AlleyTableViewCell *previousCell = (AlleyTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
//[tableView deselectRowAtIndexPath:[tableView indexPathForSelectedRow] animated:YES];
previousCell.selected = NO;
self.selectedAlley = nil;
previousCell.accessoryButton.hidden = YES;
[tableView endUpdates];
return;
}
//Else the selected cell is not the last selected cell
AlleyTableViewCell *previousCell = (AlleyTableViewCell *)[tableView cellForRowAtIndexPath:self.lastIndexPathForAlleyCells];
previousCell.selected = NO;
previousCell.accessoryButton.hidden = YES;
AlleyTableViewCell *cell = (AlleyTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.selected = YES;
cell.accessoryButton.hidden = NO;
self.selectedAlley = cell.textLabel.text;
self.lastIndexPathForAlleyCells = indexPath;
[self.tableView reloadData];
}
else if(indexPath.section == 1) {
PlayerTableViewCell *cell = (PlayerTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
//If player is not already selected
if([self playerIsSelected:cell.textLabel.text] == NO) {
//Set selected to YES and reveal buttons
cell.selected = YES;
cell.accessoryButton.hidden = NO;
cell.reorderButton.hidden = NO;
//If 8 Players are currently selected, UIAlertView informs user they have reached the limit
if([self.selectedBowlrs count] == 8) {
NSString *message = #"You can only select up to 8 players";
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Max Players Selected" message:message delegate:self cancelButtonTitle:[self okButtonTitle] otherButtonTitles:nil, nil];
alertView.tag = TAG_FULLGAME;
[alertView show];
}
else {
//Insert name into selectedBowlrs array
[self.selectedBowlrs insertObject:cell.textLabel.text atIndex:0];
//Reorder bowlrNames array
NSString *bowlrName = [self.bowlrNames objectAtIndex:indexPath.row];
[self.bowlrNames removeObjectAtIndex:indexPath.row];
[self.bowlrNames insertObject:bowlrName atIndex:0];
//Move selected row to top of section
[self moveIndexPathToTop:indexPath];
}
}
//Else the player is already selected
else {
//Set selected to NO and hide buttons
cell.selected = NO;
cell.accessoryButton.hidden = YES;
cell.reorderButton.hidden = YES;
[self.selectedBowlrs removeObject:cell.textLabel.text];
[self.bowlrNames removeObject:cell.textLabel.text];
[self.bowlrNames insertObject:cell.textLabel.text atIndex:[self.selectedBowlrs count]];
[self moveIndexPathToMiddle:indexPath];
for(int i = 0; i < [self.selectedBowlrs count]; i++) {
NSLog(#"%#", [self.selectedBowlrs objectAtIndex:i]);
}
}
}
[self performSelector:#selector(reloadData) withObject:nil afterDelay:.25];
}
//Returns the number of rows for each section
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
//For Alley section
case 0:
//If the array is empty, return 1 row for the Alley Textfield
if([self.allAlleys count] == 0)
return 1;
//Else return the number of elements in the array + 1 for the Alley Textfield
else
return [self.allAlleys count] + 1;
break;
//For Player section
case 1:{
//If the array is empty, return 1 row for the Player Textfield
if([self.bowlrNames count] == 0)
return 1;
//Else return the number of elements in the array + 1 for the Player Textfield
else
return [self.bowlrNames count] + 1;
break;
}
default:
break;
}
return 0;
}
//Set up appearance for section headers
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.tableView.bounds.size.width, 25.0)];
UILabel *headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
CGFloat isRed = 84.0/255.0;
CGFloat isGreen = 84.0/255.0;
CGFloat isBlue = 84.0/255.0;
self.headerColor = [[UIColor alloc]initWithRed:isRed green:isGreen blue:isBlue alpha:0.5];
headerLabel.backgroundColor = self.headerColor;
headerLabel.opaque = NO;
headerLabel.textColor = self.textColor;
headerLabel.highlightedTextColor = [UIColor whiteColor];
headerLabel.font = [UIFont systemFontOfSize:18.0];
headerLabel.frame = CGRectMake(0.0, 0.0, self.tableView.bounds.size.width, 25.0);
if (section == 0) {
[headerView setBackgroundColor:self.backgroundColor];
headerLabel.text = #"Alley";
[headerView addSubview:headerLabel];
}
else {
[headerView setBackgroundColor:self.backgroundColor];
headerLabel.text = #"Bowlr";
[headerView addSubview:headerLabel];
}
return headerView;
}
-(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
//Used to delete row of UITable
-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
self.indexPathForEditing = indexPath;
if(editingStyle == UITableViewCellEditingStyleDelete) {
//For Alley section
if(indexPath.section == 0) {
//Set up UIAlertView
NSString *message = #"Are you sure?";
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Delete Alley?" message:message delegate:self cancelButtonTitle:[self cancelButtonTitle] otherButtonTitles:[self deleteButtonTitle], nil];
alertView.tag = TAG_Alley;
[alertView show];
}
//For Player section
else if(indexPath.section == 1) {
//Set up UIAlertView
NSString *message = #"All information for this Bowlr will be deleted";
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Delete Bowlr?" message:message delegate:self cancelButtonTitle:[self cancelButtonTitle] otherButtonTitles:[self deleteButtonTitle], nil];
alertView.tag = TAG_Player;
[alertView show];
}
}
[self performSelector:#selector(reloadData) withObject:nil afterDelay:.25];
}
Okay, I think there's two basic things you need to remember here.
(1) You must never add something to the cell as a subview. Add it only to the cell's contentView. This code is wrong: [alleyCell addSubview:self.alleyField];
(2) These cells are being reused. You may have 100 rows but only 10 cells, being constantly reused as the user scrolls. Therefore you must completely set up every cell from an empty state, and if it isn't in the empty state to start with, you need to get it into the empty state. If you add a textfield to a cell in one pass thru cellForRowAtIndexPath, you must remember to remove the textfield in every other pass thru cellForRowAtIndexPath, or the textfield can show up in other rows because another row might reuse that same cell.
(See also the discussion towards the end of this section of my book: http://www.apeth.com/iOSBook/ch21.html#_the_three_big_questions It discusses a simple consequence of forgetting that the cells are reused.)
Also, I need hardly add that frame matters. You are adding a subview, but I have no idea what its frame is. With the right (meaning wrong) frame value, that subview could appear outside the cell. Also, are you using cells of different heights? If so, remember that because the cell is being reused, its height can change. Thus, autoresizing behavior can cause the frame to change.
I am having real troubles adding a UIImageView to a single UITableView cell. In my Storyboard I have a UITableViewController and four prototype dynamic cells. Three of them are just fine as normal left detail cells and they work fine. However one of them I need to have a UIImageView in.
So I have added said view to the cell, given the cell a custom class with a property so I can access the image view.
I have the following cells:
Title cell.
Image Cell.
URL Cell.
Notes Cell.
The contents of the table view change depending on whether the user wants to add a URL, note or image. So the user always sees the title cell with one of the others.
Here is my code and for whatever reason I just can't get the UIImageView to display on that image cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
//0 = Image
if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 0)
{
if (indexPath.row == 0) CellIdentifier = #"titleCell";
if (indexPath.row == 1) CellIdentifier = #"imageCell";
if (indexPath.row == 2) CellIdentifier = #"notesCell";
}
//1 = URL
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 1)
{
if (indexPath.row == 0) CellIdentifier = #"titleCell";
if (indexPath.row == 1) CellIdentifier = #"urlCell";
if (indexPath.row == 2) CellIdentifier = #"notesCell";
}
//2 = Notes
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 2)
{
if (indexPath.row == 0) CellIdentifier = #"titleCell";
if (indexPath.row == 1) CellIdentifier = #"notesCell";
}
ScrapbookImageDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[ScrapbookImageDetailCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier];
cell.editingAccessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
[cell setBackgroundColor:[UIColor colorWithRed:250.0f/255.0f green:250.0f/255.0f blue:250.0f/255.0f alpha:1.0f]];
[cell setSelectionStyle:UITableViewCellSelectionStyleGray];
cell.textLabel.adjustsFontSizeToFitWidth = YES;
cell.textLabel.text = [firstSection objectAtIndex:indexPath.row];
cell.detailTextLabel.font = [UIFont fontWithName:#"HelveticaNeue" size:13.0f];
cell.detailTextLabel.numberOfLines = 0;
cell.accessoryView = nil;
switch (indexPath.section)
{
case 0:
switch (indexPath.row)
{
case 0:
{
cell.detailTextLabel.text = scrapbook.title;
}
break;
case 1:
{
//0 = Image
if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 0)
{
cell.detailTextLabel.text = nil;
cell.iv.image = [UIImage imageNamed:#"image.png"];
}
//1 = URL
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 1)
{
cell.detailTextLabel.text = scrapbook.url;
}
//2 = Notes
else if ([[NSUserDefaults standardUserDefaults] integerForKey:#"NewScrapbookEntry"] == 2)
{
cell.detailTextLabel.text = scrapbook.notes;
}
}
break;
case 2:
{
cell.detailTextLabel.text = scrapbook.notes;
}
break;
default:
break;
}
break;
default:
break;
}
return cell;
}
Why are you changing the identifier value? The thing you just have to do is make custom cell, and in height for row, check if it's your desired row, and return with height of image else default size, and in cell for row method, again check desired row and add the image you want to add else make the imageview nil.
I can click on the field, and it momentarily turns blue, but those events plus makeFirstResponder together do not cause the keyboard to show on a UITextField.
Plain vanilla code follows; I include it so others can discern what is NOT there and therefore what, presumably, with solve the problem.
I put in leading spaces to format this question more like code, but the parser seems to have stripped them, thus leaving left-justified code. Sorry!
UITextFieldDelete, check:
#interface RevenueViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITextFieldDelegate> {
UILabel *sgmntdControlLabel;
UISegmentedControl *sgmntdControl;
UITableView *theTableView;
}
#property(nonatomic,retain) UISegmentedControl *sgmntdControl;
#property(nonatomic,retain) UILabel *sgmntdControlLabel;
Delegate and source, check.
-(void)loadView;
// code
CGRect frameTable = CGRectMake(10,0,300,260);
theTableView = [[UITableView alloc] initWithFrame:frameTable style:UITableViewStyleGrouped];
[theTableView setDelegate:self];
[theTableView setDataSource:self];
// code
[self.view addSubview:theTableView];
[super viewDidLoad];
}
Insert UITextField to cell, check.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger sectionNmbr = [indexPath section];
NSInteger rowNmbr = [indexPath row];
NSLog(#"cellForRowAtIndexPath=%d, %d",sectionNmbr,rowNmbr);
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
switch (sectionNmbr) {
case 0:
if (rowNmbr == 0) {
cell.tag = 1;
cell.textLabel.text = #"Label for sctn 0, row 0";
UITextField *tf = [[UITextField alloc] init];
tf.keyboardType = UIKeyboardTypeNumberPad;
tf.returnKeyType = UIReturnKeyDone;
tf.delegate = self;
[cell.contentView addSubview:tf];
}
if (rowNmbr == 1) {
cell.tag = 2;
cell.textLabel.text = #"Label for sctn 0, row 1";
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
break;
}
}
Successfully end up where we want to be (?), no check, (and no keyboard!):
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"didSelectRowAtIndexPath");
switch (indexPath.section) {
case 0:
NSLog(#" section=0, rowNmbr=%d",indexPath.row);
switch (indexPath.row) {
case 0:
UITableViewCell *cellSelected = [tableView cellForRowAtIndexPath: indexPath];
UITextField *textField = [[cellSelected.contentView subviews] objectAtIndex: 0];
[ textField setEnabled: YES ];
[textField becomeFirstResponder];
// here is where keyboard will appear?
[tableView deselectRowAtIndexPath: indexPath animated: NO];
break;
case 1:
// code
break;
default:
break;
}
break;
case 1:
// code
break;
default:
// handle otherwise un-handled exception
break;
}
}
Thank you for your insights!
are you sure that
[[cellSelected.contentView subviews] objectAtIndex: 0];
is returning what you expect it to? Try checking it with the debugger