iPhone – How do I update dynamic change line numbers in UITABLE CORRECLTY (and their cell contents)?

I am trying to create a UITableViewController subclass to provide me with UITableView through my application settings. I am having trouble reloading data about the state of UISwtitch.

The table has 3 sections:

section 1 – one row constantly

section 2 – UISwitch in the first row< br> making this section consist of 1 or 3
rows (depending on the state of
UISwitch)

section 3 – UISwitch in the first row
making this section consist of 1 or 3
rows (depending on the state of
UISwitch), but with another UISwitch
and additional rows data.

- (NSInteger)tableView:(UITableView *) tableView numberOfRowsInSection:(NSInteger)section {

switch (section )
{
case 0:
return 1;
break;
case 1:
if (limit_password_attempts )
return 3;
else
return 1;
break;
case 2:
if (lock_when_i nactive )
return 3;
else
return 1;
break;
default:
return 1;
break;
}
}

The two UISwitch-s in the first row of the first and third parts change BOOL respectively

BOOL limit_password_attempts;
BOOL lock_when_inactive;

My problem is when I switch UISwitch (for expmpl) in the second part, I want my second part to extend by 2 lines and fill with new Data. It stretches, but the new cell doesn’t look like what I want. The second row becomes a copy of the first row in the next section (the third section with UISwitch in the first row), if not before the third section Expand, the third row returns correct, if it is, then the row becomes a copy of the second row of the third part.

So my cell customization looks like this, I think the error is here .

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = nil;< br /> static NSString *EnabledCellIdentifier = @"Enabled";
cell = [tableView dequeueReusableCellWithIdentifier:EnabledCellIdentifier];

if (cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithStyle: UITableViewCellStyleDefa ult
reuseIdentifier: EnabledCellIdentifier]
autorelease];

cell.detailTextLabel.enabled = YES;

switch (indexPath.section )
{
case 0: // section 1
cell.textLabel.text = @"Banks settings";
break;
case 1: // section 2
{
switch (indexPath.row )
{
case 0:
{
cell.textLabel.text = @"Limit passwords attempts";
UISwitch* actSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[cell setEditingAccessoryView: actSwitch];

[actSwitch setTag: indexPath.section];
[actSwitch addTarget: self
action: @selector(actSwitchChange d:)
forControlEvents: UIControlEventValueChanged];

[self.view addSubview:actSwitch];
[actSwitch setOn:YES animated:NO];
[actSwitch setOn :NO animated:NO];

actSwitch.on = NO;
[cell addSubview: actSwitch];
cell.accessoryView = actSwitch;
[actSwitch release] ;
break;
}
case 1:
cell.textLabel.text = @"Lock after 3 atempts";
break;
case 2:
cell.textLabel.text = @"Lock for 30 min";
break;
default:
break;
}
break;
}
case 2: // section 3
{
switch (indexPath.row )
{
case 0:
{
cell.textLabel. text = @"Lock when inactive";
UISwitch* pactSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[cell setEditingAccessoryView: pactSwitch];

[pactSwitch setTag: indexPath.section];
[pactSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

[self. view addSubview:pactSwitch];
[pactSwitch setOn:YES animated:NO];
[pactSwitch setOn:NO animated:NO];

pactSwitch.on = NO;
[cell addSubview: pactSwitch];
cell.accessoryView = pactSwitch;
[pactSwitch release];


break;
}
case 1:
cell.textLabel.text = @"Lock when inactive for 20 min";
break;
case 2:
cell.textLabel.text = @"Unlock key" ;
break;
default:
break;
}
break;
}
default:
NSLog(@"% d", indexPath.section );
break;
}
}
return cell;
}

It looks like something is hidden in me The row data in the array is filled with onec, and the table controller updates the table in a certain way, depending on the rows that appear, only updates them. When adding rows in the section, why does it copy. This is like an array In the node. I think it must advance the cell, but not just copy.
Do I have to delete rows in some way to make this kind of table update?
I think I am missing something basic here. Some MVC concepts? But is it really necessary to build a data model here? Why? If so, what should I do?

Thank you for any answers.
Have a nice day.

This is in my code. I just didn’t write it down in my question.< br>Call the reloadData method after switching UISwtitch:

[pactSwitch setTag: indexPath.section];
[actSwitch addTarget: self
action: @selector( actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

In the actSwitchChanged method:

-(void) actSwitchChanged: (UISwitch*) pSwitch { 

if ([pSwitch tag] == 1) //section 2
limit_password_attempts = !limit_password_attempts ;
else if ([pSwitch tag] == 2) //section 3
lock_when_inactive = !lock_when_inactive;
[self.tableView reloadData];

}

So reloadData will change the content of viewTable, but it is not what I imagined That way.

Any ideas?

You are right, you have implemented the wrong – (UITableViewCell *)tableView:(UITableView * )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. If you are looking for a simple way to implement cells with different layouts without subclassing UITableViewCell, then you need an example for you:

0) Read this to understand UITableView programming in depth

1) The method returns a cell of each layout

- (NSString*)typeOfCellForIndexPath: (NSIndexPath*)indexPath {
NSString *ret = @"CellWithoutSwitch";
if(indexPath.section != 0 && idextPath.row == 0) {
ret = @"CellWithSwitch" ;
}
return ret;
}

2) The method returns each type of cell

- (UITableViewCell*)cellForType:(NSString*)aType {
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: aType] autorelease];
cell.detailTextLabel.enabled = YES;
if ([aType isEqualToString:@"CellWithSwitch"]) {
// just copy of your code
// this does not need here
cell.textLabel.text = @"Limit passwords attempts";
// this needs but with CGRectMake(...) insted of CGRectZero
UISwitch* actSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];
// this does not need
[cell setEditingAccessoryView: actSwitch];
// this needs but for switch tag you should use #define SWITCH_TAG 777
[actSwitch setTag: indexPath. section];
// this does not need here
[actSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

// wrong part of code
[self.view addSubview:actSwitch];
// this does not need here
[actSwitch setOn:YES animated:NO];
// wrong part of code
[actSwitch setOn:NO animated:NO];

actSwitch.on = NO;
// ok
[cell addSubview: actSwitc h];
// wrong part of code
cell.accessoryView = actSwitch;
// ok
[actSwitch release];
}
}< /pre>

3) Method of configuring cells with paths

- (void)cofigureCell:(UITableViewCell*)cell forIndexPath:(NSIndexPath*)indexPath {
// just copy of your code
switch (indexPath.section )
{
case 0: // section 1
cell.textLabel.text = @"Banks settings" ;
break;
case 1: // section 2
{
switch (indexPath.row )
{
case 0:
{
cell.textLabel.text = @"Limit passwords attempts";
/* this part of code replace with UISwitch* actSwitch = (UISwitch*)[cell viewWithTag:SWITCH_TAG];
UISwitch* actSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[cell setEditingAccessoryView: actSwitch];

[actSwitch setTag: indexPath.section];*/

[actSwitch addTarget: self
action : @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];
/* all what you need now that cofigure an state of switch with limit_password_attempts variable-[actSwitch setOn:limit_password_attempts animated:NO];
// this is junk
[self.view addSubview:actSwitch];
[actSwitch setOn:YES animated:NO];
[actSwitch setOn:NO animated:NO];

actSwitch.on = NO;
[cell addSubview: actSwitch];
cell.accessoryView = actSwitch;
[actSwitch release];*/
break;
}
case 1:
cell.textLabel.text = @"Lock after 3 atempts";
break;
case 2:
cell .textLabel.text = @"Lock for 30 min";
break;
default:
break;
}
break;
}

case 2: // section 3
{
switch (indexPath.row )
{
case 0:
{
// look at previous configuration of switch
cell.textLabel.text = @"Lock when inactive";
UISwitch* pactSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[ cell setEditingAccessoryView: pactSwitch];

[pactSwitch setTag: indexPath.section];
[pactSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];
< br /> [self.view addSubview:pactSwitch];
[pactSwitch setOn:YES animated:NO];
[pactSwitch setOn:NO animated:NO];

pactSwitch. on = NO;
[cell addSubview: pactSwitch];
cell.accessoryView = pactSwitch;
[pactSwitch release];


break;
}
case 1:
cell.textLabel.text = @"Lock when inactive for 20 min";
break;
case 2:
cell.textLabel.text = @"Unlock key";
break;
default:
break;
}
break;
}
default:
NSLog(@"%d", indexPath.section );
break;
}
}

4) Implement the last method< /p>

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = nil;
// get type for indexPath
static NSString *EnabledCellIdentifier = [self typeOfCellForIndexPath:idextPath];
cell = [tableView dequeueReusableCellWithIdentifier:EnabledCellIdentifier];

if (cell == nil )
{
// create a cell with needed type
cell = [self cellForType:EnabledCellIdentifier];
}

// cofigure the cell< br /> [self cofigureCell:cell forIndex Path:indexPath];

return cell;
}

I am trying to create a UITableViewController subclass through my application Settings provide me with UITableView. I have a problem reloading the data about the state of UISwtitch.

The table has 3 parts:

section 1 – one row constantly

section 2 – UISwitch in the first row
making this section consist of 1 or 3
rows (depending on the state of
UISwitch)

section 3 – UISwitch in the first row
making this section consist of 1 or 3
rows (depending on the state of
UISwitch), but with another UISwitch
and additional rows data.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

switch (section )
{
case 0:
return 1;
break;
case 1:
if (limit_password_attempts )
return 3;
else
return 1;
break;
case 2 :
if (lock_when_inactive )
return 3;
else
return 1;
break;
default:
return 1;
break;
}
}

The two UISwitch-s in the first row of the first and third parts change BOOL respectively

< /p>

BOOL limit_password_attempts;
BOOL lock_when_inactive;

My problem is when I switch UISwitch (for exmpl) in the second part, I want my second part Extend 2 rows, and fill with new data. It extends, but the new cell does not look like what I want. The second row becomes a copy of the first row in the next section (the first row has the third section with UISwitch) , If it is not expanded before the third section, the third row returns correct, if it is, the row becomes a copy of the second row of the third section.

So my cell customization looks like this , I think the error is here.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = nil;
static NSString *EnabledCellIdentifier = @"Enabled";
cell = [tableView dequeueReusableCellWithIdentifier:EnabledCellIdentifier];

if (cell == nil)
{
cell = [[[UITableViewCell alloc]
initWithSty le: UITableViewCellStyleDefault
reuseIdentifier: EnabledCellIdentifier]
autorelease];

cell.detailTextLabel.enabled = YES;

switch (indexPath.section )
{
case 0: // section 1
cell.textLabel.text = @"Banks settings";
break;
case 1: // section 2
{
switch (indexPath.row )
{
case 0:
{
cell.textLabel.text = @"Limit passwords attempts";
UISwitch* actSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[cell setEditingAccessoryView: actSwitch];

[actSwitch setTag: indexPath.section];
[actSwitch addTarget: self
actio n: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

[self.view addSubview:actSwitch];
[actSwitch setOn:YES animated:NO];
[actSwitch setOn:NO animated:NO];

actSwitch.on = NO;
[cell addSubview: actSwitch];
cell.accessoryView = actSwitch;
[actSwitch release];
break;
}
case 1:
cell.textLabel.text = @"Lock after 3 atempts";
break;
case 2:
cell.textLabel.text = @"Lock for 30 min";
break;
default:
break;
}
break ;
}

case 2: // section 3
{
switch (indexPath.row )
{
case 0:
{
cell.textLabel.text = @"Lock when inactive";
UISwitch* pactSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[cell setEditingAccessoryView: pactSwitch];

[pactSwitch setTag: indexPath.section];
[pactSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

[self.view addSubview:pactSwitch];
[pactSwitch setOn:YES animated:NO];
[pactSwitch setOn:NO animated:NO];
< br /> pactSwit ch.on = NO;
[cell addSubview: pactSwitch];
cell.accessoryView = pactSwitch;
[pactSwitch release];


break;
}
case 1:
cell.textLabel.text = @"Lock when inactive for 20 min";
break;
case 2:
cell .textLabel.text = @"Unlock key";
break;
default:
break;
}
break;
}
default :
NSLog(@"%d", indexPath.section );
break;
}
}
return cell;
}

It looks like there is some row data hidden in my array, i.e. fill onec, the table controller updates the table in some way, depending on the rows that appear, only update them. When adding rows in the section, why It will be copied. This is like a node in an array. I think it must advance the cell, but not just copy.
Do I have to delete rows in some way to make this table update?
I think I am missing something basic here. Some MVC concepts? But is it really necessary to build a data model here? Why? If so, what should I do?

Thank you for any answers.
Have a nice day.

This is in my code. I just didn't write it down in my question.< br>Call the reloadData method after switching UISwtitch:

[pactSwitch setTag: indexPath.section];
[actSwitch addTarget: self
action: @selector( actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

In the actSwitchChanged method:

-(void) actSwitchChanged: (UISwitch*) pSwitch { 

if ([pSwitch tag] == 1) //section 2
limit_password_attempts = !limit_password_attempts ;
else if ([pSwitch tag] == 2) //section 3
lock_when_inactive = !lock_when_inactive;
[self.tableView reloadData];

}

So reloadData will change the content of viewTable, but it is not what I imagined That way.

Any ideas?

You are right, you implemented the wrong – (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath. If you Are looking for an easy way to implement cells with different layouts without subclassing UITableViewCell, then you need an example for you:

0) Read this to understand UITableView programming in depth

p>

1) The method returns a cell of each layout

- (NSString*)typeOfCellForIndexPath:(NSIndexPath*)indexPath {
NSString * ret = @"CellWithoutSwitch";
if(indexPath.section != 0 && idextPath.row == 0) {
ret = @"CellWithSwitch";
}
return ret ;
}

2) The method returns each type of cell

- (UITableViewCell*)cellForType:(NSString*)aType { 
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: aType] autorelease];
cell.detailTextLabel.enabled = YES;
if ([aType isEqualToString:@"CellWithSwitch" ]) {
// just copy of your code
// this does not need here
cell.textLabel.text = @"Limit passwords attempts";
// this needs but with CGRectMake(...) insted of CGRectZero
UISwitch* actSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];
// this does not need
[ cell setEditingAccessoryView: actSwitch];
// this needs but for switch tag you should use #define SWITCH_TAG 777
[actSwitch setTag: indexPath.section];
// this does not need here< br /> [actSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

// wrong part of code
[self. view addSubview:actSwitch];
// this does not need here
[actSwitch setOn:YES animated:NO];
// wrong part of code
[actSwitch setOn:NO animated:NO];

actSwitch.on = NO;
// ok
[cell addSubview: actSwitch];
// wrong part of code
cell.a ccessoryView = actSwitch;
// ok
[actSwitch release];
}
}

3) Method of configuring cells with paths

- (void)cofigureCell:(UITableViewCell*)cell forIndexPath:(NSIndexPath*)indexPath {
// just copy of your code
switch (indexPath.section)
{
case 0: // section 1
cell.textLabel.text = @"Banks settings";
break;
case 1: // section 2< br /> {
switch (indexPath.row )
{
case 0:
{
cell.textLabel.text = @"Limit passwords attempts";
/* this part of code replace with UISwitch* actSwitch = (UISwitch*)[cell viewWithTag:SWITCH_TAG];
UISwitch* actSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[cell setEditingAccessoryView : actSwitch];

[actSwitch setTag: indexPath.section];*/

[actSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];
/* all what you need now that cofigure an state of switch with limit_password_attempts variable-[actSwitch setOn:limit_password_attempts animated:NO];
// this is junk
[self.view addSubview:actSwitch];
[actSwitch setOn:YES animated:NO];
[actSwitch setOn:NO animated:NO];

actSwitch.on = NO;
[cell addSubview: actSwitch];
cell.accessoryView = actSwitch;
[actSwitch release];*/
break;
}
case 1:
cell.textLabel.text = @"Lock after 3 atempts";
break;
case 2:
cell.textLabel.text = @"Lock for 30 min ";
break;
default:
break;
}
break;
}

case 2: // section 3
{
switch (indexPath.row )
{
case 0:
{
// look at previous configuration of switch
cell .textLabel.text = @"Lock when inactive";
UISwitch* pactSwitch = [[UISwitch alloc] initWithFrame: CGRectZero ];

[cell setEditingAccessoryView: pactSwitch];
< br /> [pactSwitch setTag: indexPat h.section];
[pactSwitch addTarget: self
action: @selector(actSwitchChanged:)
forControlEvents: UIControlEventValueChanged];

[self.view addSubview:pactSwitch ];
[pactSwitch setOn:YES animated:NO];
[pactSwitch setOn:NO animated:NO];

pactSwitch.on = NO;
[cell addSubview: pactSwitch];
cell.accessoryView = pactSwitch;
[pactSwitch release];


break;
}
case 1:
cell.textLabel.text = @"Lock when inactive for 20 min";
break;
case 2:
cell.textLabel.text = @"Unlock key";< br /> break;
default:
break;
}
break;
}
default:
NSLog(@"%d", indexPath. section );
break;
}
}

4) Implement the last method

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = nil;
// get type for indexPath
static NSString *EnabledCellIdentifier = [self typeOfCellForIndexPath:idextPath];
cell = [tableView dequeueReusableCellWithIdentifier:EnabledCellIdentifier];

if (cell == nil)
{
// create a cell with needed type
cell = [self cellForType:EnabledCellIdentifier];
}

// cofigure the cell
[self cofigureCell:cell forIndexPath:indexPath];

return cell;
}

Leave a Comment

Your email address will not be published.