Reputation: 51
I have 11 or more number of rows. Need to create a UISwitch only in the first cell. The UIswitch gets duplicated when i click on any row.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:EN_MoreTableViewCell];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:EN_MoreTableViewCell];
cell.backgroundColor = [UIColor clearColor];
}
cell.textLabel.text = languageObject.name;
[cell.textLabel setFont:font];
if (indexPath.row == 0 && [languageObject.name isEqual: @"All Languages"]) {
if (!mySwitch) {
mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(_languageListTableView.frame.size.width - 60, 0, 40, 40)];
[cell.contentView addSubview:mySwitch];
}
cell.accessoryType = UITableViewCellAccessoryNone;
}
else { //other cell code//
}
Please help.
Upvotes: 0
Views: 463
Reputation: 131408
This is a classic iOS newbie question. This confuses the hell out of most of us when we first use table views (it certainly confused me at first.)
Cells get created once and then reused over and over. The function dequeueReusableCellWithIdentifier()
returns a recycled cell if one is available, or creates a new one from your cell prototype if not.
If you get a recycled cell, it will already have your switch added.
The cleanest way to handle this is to define a cell prototype using a custom subclass of UITableViewCell
that has all your fields already added and connected as outlets to the cell. Then when you dequeue a cell, simply cast it to your custom UITableViewCell
class and use the properties you've defined to access your custom fields (Your switch, in this case.)
A recycled cell may also contain values in it's other fields (Like if you've set a label field to contain a string, it will still contain the string.) You need to clear out old values and completely configure a recycled cell. (The custom cell class and prototype doesn't fix this problem. You always need to fully configure every field in your cell.)
Upvotes: 2
Reputation: 213
You just hide the switch where you don't want to display and set the action for that switch dynamically for the particular indexpath you want
Upvotes: 0
Reputation: 11
Add a UISwitch in the storyboard. Connect outlet. In tableview's cellforrowatindexpath, if the index is 0 set hidden=false else set hidden=true. Hope this works.
Upvotes: 0
Reputation: 62686
Sometimes a custom cell is a big hammer for just adding a single view to an otherwise perfectly good standard UITableViewCell
. For those occasions, lazy creation is a nice pattern to get views built exactly once on reused cells (or even as any subview of any view). It works like this:
// in your cellForRowAtIndexPath, after dequeuing cell
UISwitch *switch = (UISwitch *)[cell viewWithTag:64]; // make up a unique tag
if (!switch) {
switch = [[UISwitch alloc] initWithFrame:...];
switch.tag = 64; // 64 must match the tag above
[cell addSubview:switch];
}
// here, switch is always valid, but only created when it was absent
Upvotes: 0
Reputation: 19602
Either:
Create two prototype cells in Storyboard, one with and one without UISwitch
and dequeue the first only if indexPath.row == 0
.
Or:
Add the UISwitch
to your cell in Storyboard, make an IBOutlet
to your cell and set self.mySwitch.isHidden = true
in cells prepareForReuse()
.
This way the default state when reusing the cell is with hidden switch.
Later if indexPath.row == 0
, set cell.mySwitch.isHidden = false
.
Upvotes: 1
Reputation: 2410
It's because cells are reused. You can either remove all existing subviews in -[UITableViewDataSource tableView:cellForRowAtIndexPath:]
or create a new cell for every row.
Upvotes: 0