Uiswitch in uitableviewcell reset when scroll up or down? - ios

I have a problem with my UISwitch inside a UITableViewCell. When I change the value of one switch then scroll up or down all switches are messed up. I use an array to store state for each switch due to reusability they are still messed up every time.
Here is cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"Cell"];
}
UISwitch *switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
CGRect switchFrame = switchController.frame;
[switchController setOn:YES animated:NO];
//set its x and y value, this you will have to determine how to space it on the left side
switchFrame.origin.x = 50.0f;
switchFrame.origin.y = 10.0f;
switchController.frame = switchFrame;
[switchController addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[cell addSubview:switchController ];
UILabel *label ;
label=(UILabel *)[cell viewWithTag:1];
NSString *value = [[mainArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
label.text = value;
label.textAlignment = NSTextAlignmentRight;
label.autoresizingMask = UIViewAutoresizingFlexibleRightMargin;
//This for persist switch state when scroll up or down
if ([[[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row ]isEqualToString:#"ON"])
{
switchController.on=YES;
}
else
{
switchController.on=NO;
}
return cell;
}
Here is SwitchChanged event :
-(void)switchChanged:(UISwitch *)sender
{
UITableViewCell *cell = (UITableViewCell *)[[sender superview] superview];
NSIndexPath *index=[mainTableView indexPathForCell:cell];
if (sender.on)
{
[[self.SwitchArray objectAtIndex:index.section] replaceObjectAtIndex:index.row withObject:#"ON"];
NSString *word= [[self.mainArray objectAtIndex:index.section ] objectAtIndex:index.row];
}
else
{
//call the first array by section
[[self.SwitchArray objectAtIndex:index.section] replaceObjectAtIndex:index.row withObject:#"OFF"];
NSString *word= [[self.mainArray objectAtIndex:index.section ] objectAtIndex:index.row];
}
[padFactoids setObject:[NSKeyedArchiver archivedDataWithRootObject:SwitchArray] forKey:#"savedArray"];
[padFactoids synchronize];
}
I will appreciate your help so much.

In your header file declare an NSMutableArray, let's name it switchStates.
In your viewDidLoad, allocate memory and add object with the string "OFF" according to number of switches:
switchStates = [[NSMutableArray alloc] init];
for (int i; i <= switchesArray.count; i++) {
[switchStates addObject:#"OFF"];
}
In your method which runs when the switch is triggered:
NSString *theSwitchPosition = [NSString stringWithFormat:#"%#", switchControl.on ? #"ON" : #"OFF"];
[switchStates replaceObjectAtIndex:aPath.row withObject:theSwitchPosition];
After that, in the method where you create your switches:
if ([[switchStates objectAtIndex:indexPath.row] isEqualToString:#"ON"]) {
mySwitch.on = YES;
} else {
mySwitch.on = NO;
}
This worked for me, good luck..

I am not sure whether this causes your problem, but it will certainly cause other related problems.
Each time when a cell was moved off screen and a next one appears, the one that just moved off screen will be reused.
But you add a new switch object every time to the cell. You are far better off creating those only within the cell==nil block. Give it a tag and use the tag to fetch the object upon reusage as you do with the lable object.

You're creating a new switch every time the tableView is asking for a cell. You only want to create the switch once for each cell:
UISwitch *switchController;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"Cell"];
switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
CGRect switchFrame = switchController.frame;
[switchController setOn:YES animated:NO];
//set its x and y value, this you will have to determine how to space it on the left side
switchFrame.origin.x = 50.0f;
switchFrame.origin.y = 10.0f;
switchController.frame = switchFrame;
[switchController addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:switchController ];
switchController.tag = 123; //Arbitrary number...can be anything
}
else {
switchController = (UISwitch *)[cell.contentView viewWithTag:123];
}
//Now set the switch state according to your data model array
It's also generally a better practice to add subviews to the cell's contentView rather than the cell itself.

Related

How can I send the relevant UITextField text data to the function in a collapsable UITableView?

I have this collapsable UITableView where there is a UITextField and a UIButton in the last cell in each table section. I would like to send the text in the UITextField to the function that is called by the UIButton that is next to it in the same cell, but I am baffled in how to achieve this. Thanks in advance for the help!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([self tableView:_tableView canCollapseSection:indexPath.section])
{
int num = 1;
if (self.chat[indexPath.section - 1][#"num"] != nil)
num = [self.chat[indexPath.section - 1][#"num"] intValue] + 1;
if (!indexPath.row)
{
cell.textLabel.text = self.chat[indexPath.section - 1][#"msg"]; // only top row showing
if ([expandedSections containsIndex:indexPath.section])
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeUp];
}
else
{
cell.accessoryView = [DTCustomColoredAccessory accessoryWithColor:[UIColor grayColor] type:DTCustomColoredAccessoryTypeDown];
}
}
else if (indexPath.row < num && indexPath.row >= 1)
{
cell.textLabel.text = self.chat[indexPath.section - 1][key];
cell.accessoryView = nil;
}
else
{
///////////////////////////////////////////
////////This is the important part/////////
///////////////////////////////////////////
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(14, 6, 245, 31)];
self.sendButton = [[UIButton alloc] initWithFrame:CGRectMake(265, 1, 50, 40)];
[self.sendButton setTitle:#"Reply" forState:UIControlStateNormal];
[self.sendButton setTitleColor:UIColorFromRGB(0x960f00) forState:UIControlStateNormal];
[cell addSubview:self.sendButton];
[self.sendButton addTarget:self action:#selector(sendReply:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:field];
cell.accessoryView = nil;
}
}
else
{
cell.accessoryView = nil;
cell.textLabel.text = #"Normal Cell";
}
return cell;
}
Give some unique tag to textfield and button by below way:
///////////////////////////////////////////
////////This is the important part/////////
///////////////////////////////////////////
UITextField *field = [[UITextField alloc] initWithFrame:CGRectMake(14, 6, 245, 31)];
self.sendButton = [[UIButton alloc] initWithFrame:CGRectMake(265, 1, 50, 40)];
[self.sendButton setTitle:#"Reply" forState:UIControlStateNormal];
[self.sendButton setTitleColor:UIColorFromRGB(0x960f00) forState:UIControlStateNormal];
self.sendButton.tag = indexPath.section *1000 + indexPath.row;
[cell addSubview:self.sendButton];
[self.sendButton addTarget:self action:#selector(sendReply:) forControlEvents:UIControlEventTouchUpInside];
field.tag = self.sendButton.tag + 1;
[cell addSubview:field];
cell.accessoryView = nil;
Now on button event,
-(void) sendReply:(UIButton *)sender
{
UITextField *field = [YOOUR_TABLE_VIEW viewWithTag:sender.tag + 1];
//Do you coding here
}
Make a Custom UITableViewCell that has uitextfield and a button on it and make a protocol/delegate of that custom uitableviewcell you've created.. so you can have more control of your code and the event of your button in the future..
check this tutorial: http://www.codigator.com/tutorials/ios-uitableview-tutorial-custom-cell-and-delegates/
cheers
For this,
In cellForRowAtIndexPath: method where you are allocating the send button add one line just to give some identifier to send button as below,
[self.sendButton setAccessibilityIdentifier:[NSString stringWithFormat:#"%d#%d",indexPath.row,indexPath.section]];
Now, in sendReply: method,
//First get the row and section information
NSString *str=[sender accessibilityIdentifier];
NSArray *arr=[str componentsSeparatedByString:#"#"];
//Get the index path
NSIndexPath *iRowId =[NSIndexPath indexPathForRow:[[arr objectAtIndex:0] intValue] inSection:[arr objectAtIndex:1] intValue]];
//get the cell
UITableViewCell *objCell=(UITableViewCell*)[tblviwBasketCell cellForRowAtIndexPath:iRowId];
Now objCell will be the cell in which you have added the button and text view. so get the subviews of objCell and access the textfield to get the text.
As you say, there is a text field in each section. You should set the tag of your UIButton and UITextField same as indexPath.section.
Then, in the target method, use this tag value to get the relevant cell from the relevant section, and iterate over it's subviews to get your textField.
In the target method, you should do something like this:
- (void) sendReply:(id)sender {
int section = [(UIButton*)sender tag];
int row = [myTableView numberOfRowsInSection:section] - 1;//assuming it is the last cell in the section that contains your textField.
NSIndexPath* indexPath = [NSIndexPath indexPathForRow:row inSection:section];
UITableViewCell* cell = [myTableView cellForRowAtIndexPath:indexPath];
for (UIView* vu in cell.subviews) {
if ([vu isKindOfClass:[UITextField class]]) {
NSString* textString = [(UITextField*)vu text];
//perform any tasks you want with the text now
}
}
}
You can simply use viewWithTag:, since it does an iterative search, but all the extra code is to avoid iterating over all the cells before reaching your relevant cell.

TableView Behaving Weirdly

My tableView (phpush) behaves very unusually. The cell from section 0 randomly appears at different rows, and sometimes disappears from the top of the table. Here are some methods that I think may be causing the problem:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (tableView==_phpush) {
if (indexPath.section==0) {
UIButton *pushButtonDate;
UIButton *pushButtonPush;
UIButton *edit;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
pushButtonPush = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[pushButtonPush addTarget:self action:#selector(pushButtonPushPressed:)forControlEvents UIControlEventTouchUpInside];
[pushButtonPush setTitle:#"Push-Ups" forState:UIControlStateNormal];
pushButtonPush.frame = CGRectMake(150,7,97,30);
pushButtonDate.tag = 3;
[cell.contentView addSubview:pushButtonPush];
pushButtonDate = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[pushButtonDate addTarget:self action:#selector(pushButtonDatePressed:)forControlEvents: UIControlEventTouchUpInside];
[pushButtonDate setTitle:#"Date" forState:UIControlStateNormal];
pushButtonDate.frame = CGRectMake(11,7,97,30);
pushButtonDate.tag = 4;
[cell.contentView addSubview:pushButtonDate];
edit = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[edit addTarget:self action:#selector(editButtonPressed:)forControlEvents:UIControlEventTouchUpInside];
[edit setTitle:#"Edit" forState:UIControlStateNormal];
edit.frame = CGRectMake(200,7,97,30);
edit.tag = 5;
[cell.contentView addSubview:edit];
}
else {
pushButtonPush = [cell.contentView viewWithTag:(3)];
pushButtonDate = [cell.contentView viewWithTag:(4)];
edit = [cell.contentView viewWithTag:5];
}
return cell;
}
else {
UILabel *pushLabel;
UILabel *pushLabel2;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
pushLabel = [[UILabel alloc]initWithFrame:CGRectMake(150,7,97,30)];
pushLabel2 = [[UILabel alloc]initWithFrame:CGRectMake(10,7,150,30)];
NSArray *array;
if (sortByDate==true) {
array = [[pushDictionary allKeys]sortedArrayUsingSelector
:#selector(localizedCaseInsensitiveCompare:)];
}
else {
array = [pushDictionary keysSortedByValueUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
}
pushLabel.text = [pushDictionary valueForKey:[array objectAtIndex:indexPath.row]];
NSString *pushLabel2String = [[array objectAtIndex:indexPath.row] substringToIndex:MIN(10, [[array objectAtIndex:indexPath.row] length])];
NSArray *pushLabel2Array = [pushLabel2String componentsSeparatedByString:#"-"];
pushLabel2.text = [NSString stringWithFormat:#"%#/%#/%#",[pushLabel2Array objectAtIndex:1],[pushLabel2Array objectAtIndex:2],[pushLabel2Array objectAtIndex:0]];
pushLabel.tag = 1;
pushLabel2.tag = 2;
[cell.contentView addSubview:pushLabel];
[cell.contentView addSubview:pushLabel2];
}
else {
pushLabel = [cell.contentView viewWithTag:1];
pushLabel2 = [cell.contentView viewWithTag:2];
}
return cell;
}
}
else {
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
else {
}
return cell;
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView==_phpush) {
return 2;
}
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView==_phpush) {
if (section==0) {
return 1;
}
return [pushDictionary allKeys].count;
}
return 1;
}
I'm wondering if there are any big mistakes I am making that would be causing this problem. I am pretty new to iOS programming, so please forgive me if I have made an obvious mistake. Do I need to post more of my code?
Thanks,
Jordan
There is a problem with your tableViewCell dequeueing.
In your else statement
else {
pushButtonPush = [cell.contentView viewWithTag:(3)];
pushButtonDate = [cell.contentView viewWithTag:(4)];
edit = [cell.contentView viewWithTag:5];
}
you never modify the contents of those buttons. Those variables you're setting are unused because you don't change the button text, or remove or add the views. If they need to do something different, you need to specify it here.
Cells are reused on scrolling and when a cell is reused it has all it's previous elements still in it.
So if you set some text in a cell, when it's reused the text is still there, so you need to set it to nil or remove it if you don't want it.
You shouldn't be allocating anything in cellForRowAtIndexPath, as when you scroll you adding more and more objects on top of the old ones.
Take a look at subclassing UITableViewCell.

User Interaction Enabled changing text color and click-ability of other sections

I have 3 sections in a table view and only using the middle section, section 2, to show various cells. Sections 1 and 3 only show one cell and I am making them unclickable since I want to display buttons and text on them. I made them and it was working fine until I made sections 1 and 3 userInteractionEnabled=NO.
Code: I know I can make this Object Oriented, and it was, but once this problem came up I tried to make it differently but it is still the same.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.1];
cell.selectedBackgroundView = selectedBackgroundView;
if(cell==nil) { NSLog(#"Cell is nil");}
}
if(indexPath.section == 0)
{
cell.textLabel.text = nil;
cell.accessoryView = nil;
cell.detailTextLabel.text = nil;
dosageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
amountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[dosageButton addTarget:self action:#selector(showDosages:) forControlEvents:UIControlEventTouchUpInside];
[amountButton addTarget:self action:#selector(showAmount) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:dosageButton];
[self.view addSubview:amountButton];
cell.userInteractionEnabled = NO;
return cell;
}
else if (indexPath.section == 1)
{
if (self.nameMutable.count != 0 )
{
cell.textLabel.text = [self.nameMutable objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#",[self.priceMutable objectAtIndex:indexPath.row]];
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"chevron"]];
return cell;
}
else
{
//Empty for now. Waiting for data fetching to finish
return cell;
}
}
else if (indexPath.section == 2)
{
cell.userInteractionEnabled = NO;
cell.accessoryView = nil;
cell.detailTextLabel.text = nil;
return cell;
}
else
{
NSLog(#"Something went wrong");
return cell;
}
}
For some reason my table view cell in section 1 where it is supposed to be clickable the color changes to a dark grey and is not clickable anymore. Its usually cell 3 and cell 10. Also, when I scroll down and Section 0 is no longer visible and then I scroll back up and Section 0 is visible, some of the cells become non-clickable and the color of the text changes.
Also, how can I make a certain cell, inside section 1, have bigger height because the text is too long to display and it starts to display "..." or covers the detailTextLabel. Thanks in advance.
You have to remember that these cells are being reused or 'recycled' so if you're setting userInteractionEnabled=NO for an if statement you need to set it to userInteractionEnabled=YES in your else statement, or set it as YES before all your statements. You also want to make sure that you're adding any other subviews (buttons etc.) that are unique to certain index paths to cells that are newly created, where you would stick that piece of code inside your if(cell==nil) statement. Something like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
UIView *selectedBackgroundView = [[UIView alloc] initWithFrame:CGRectZero];
selectedBackgroundView.backgroundColor = [UIColor colorWithWhite:0.0 alpha:0.1];
cell.selectedBackgroundView = selectedBackgroundView;
if(indexPath.section == 0) {
dosageButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
amountButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[dosageButton addTarget:self action:#selector(showDosages:) forControlEvents:UIControlEventTouchUpInside];
[amountButton addTarget:self action:#selector(showAmount) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:dosageButton];
[self.view addSubview:amountButton];
}
if(cell==nil) { NSLog(#"Cell is nil");}
}
cell.userInteractionEnabled = YES;
cell.accessoryView = nil;
cell.textLabel.text = nil;
cell.detailTextLabel.text = nil;
if(indexPath.section == 0)
{
cell.userInteractionEnabled = NO;
}
else if (indexPath.section == 1)
{
if (self.nameMutable.count != 0 )
{
cell.textLabel.text = [self.nameMutable objectAtIndex:indexPath.row];
cell.detailTextLabel.text = [NSString stringWithFormat:#"$%#",[self.priceMutable objectAtIndex:indexPath.row]];
cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"chevron"]];
}
else
{
//Empty for now. Waiting for data fetching to finish
}
}
else if (indexPath.section == 2)
{
cell.userInteractionEnabled = NO;
}
else
{
NSLog(#"Something went wrong");
}
return cell;
}
And if you want to change the height of certain index paths (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath Docs delegate method.

UIswitch in a table cell reused

I have a problem with uiswitch in my UITableViewCell that whenever i change a switch value in a specific cell that belongs to a specific section. All other sections cells that have same inexPath.row change . Please help ?
Here is my code of cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//UISwitch *switchview = nil ;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
UISwitch *switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
CGRect switchFrame = switchController.frame;
NSString *str = [[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
NSLog(#"string in cell%#", str);
//set its x and y value, this you will have to determine how to space it on the left side
switchFrame.origin.x = 50.0f;
switchFrame.origin.y = 10.0f;
switchController.frame = switchFrame;
[switchController addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[cell addSubview:switchController ];
[addSubview:switchController];
if ([[[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row ]isEqualToString:#"ON"])
{
switchController.on=YES;
}
else
{
switchController.on=NO;
}
return cell;
}
And here is SwitchChangedEvent:
-(void)switchChanged:(UISwitch *)sender
{
UITableViewCell *cell = (UITableViewCell *)[sender superview];
NSIndexPath *index=[mainTableView indexPathForCell:cell];
if (sender.on)
{
[[self.SwitchArray objectAtIndex:index.section] replaceObjectAtIndex:index.row withObject:#"ON"];
NSString *word= [[self.mainArray objectAtIndex:index.section ] objectAtIndex:index.row];
}
else
{
//call the first array by section
[[self.SwitchArray objectAtIndex:index.section] replaceObjectAtIndex:index.row withObject:#"OFF"];
NSString *word= [[self.mainArray objectAtIndex:index.section ] objectAtIndex:index.row];
}
[padFactoids setObject:[NSKeyedArchiver archivedDataWithRootObject:SwitchArray] forKey:#"savedArray"];
[padFactoids synchronize];
}
You have two main problems:
This code is wrong:
[cell addSubview:switchController ];
Never add a subview to the cell; add it only to the cell's contentView.
You are adding the switch every time through cellForRowAtIndexPath:. But these cells are being reused. So some cells already have the switch. Thus you are adding many switches to some cells.
As already pointed out by others, you're adding multiple switches to each cell. FTFY:
UISwitch *switchController = nil;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
switchController = [[UISwitch alloc] initWithFrame:CGRectZero];
switchController.tag = 'swch';
CGRect switchFrame = switchController.frame;
//set its x and y value, this you will have to determine how to space it on the left side
switchFrame.origin.x = 50.0f;
switchFrame.origin.y = 10.0f;
switchController.frame = switchFrame;
[switchController addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
[cell.contentView addSubview:switchController];
}
else
{
switchController = (UISwitch*)[cell.contentView viewWithTag: 'swch'];
NSAssert(switchController != nil, #"how?");
}
NSString *str = [[self.SwitchArray objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
NSLog(#"string in cell%#", str);
switchController.on = [str isEqualToString:#"ON"];
return cell;
If you look, I think you will find that you are building up multiple switches and on each cell.
As cells get reused, you add a new switch but do not remove the old one. I think this my be at least part of the cause of your problem.
UPDATE
I think I would handle this a bit differently than others. I think it will be easier for #AlanoudAldrees to remove the old switch.
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
else
{
for (UIView *view in cell.subviews)
if ([view isKindOfClass:[UISwitch class]])
[view removeFromSuperview];
}

Keeping text in UITextView after scrolling it off the screen

My table only has 2 sections. I have a UITextView as a subview in the 2nd section of my table. and a list of possible quotes in the first section.
I'm having a problem where once the user selects a particular quote which gets "pasted" into the UITextView like so:
replyTextView.text = [NSString stringWithFormat:#"#%# UserName writes... \n[\"%#\"]", replyPostCode,[separatedString objectAtIndex:indexPath.row]];
or types text into the textview, after they scroll away from the textview so it's off the screen it gets cleared. I guess this is because I keep releasing it from my table..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
NSString *replyCellIdentifier = #"replyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if ([indexPath section] == 0) {
cell = [self CreateMultilinesCell:CellIdentifier];
}
else if ([indexPath section] == 1) {
//NSLog(#"TextField");
cell = [self CreateMultilinesCell:replyCellIdentifier];
if ([indexPath row] == 0) {
replyTextView = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 300, 150)];
//replyTextView.adjustsFontSizeToFitWidth = YES;
replyTextView.textColor = [UIColor blackColor];
replyTextView.keyboardType = UIKeyboardTypeASCIICapable;
replyTextView.returnKeyType = UIReturnKeyDefault;
replyTextView.backgroundColor = [UIColor whiteColor];
replyTextView.autocorrectionType = UITextAutocorrectionTypeNo;
replyTextView.autocapitalizationType = UITextAutocapitalizationTypeNone;
replyTextView.textAlignment = UITextAlignmentLeft;
replyTextView.tag = 0;
replyTextView.editable = YES;
replyTextView.delegate = self;
replyTextView.scrollEnabled = YES;
//[replyTextView becomeFirstResponder];
//replyTextView.clearButtonMode = UITextFieldViewModeNever;
//[replyTextView setEnabled: YES];
[cell.contentView addSubview:replyTextView];
[replyTextView release];
//cell.detailTextLabel.text = #"";
}
}
}
//NSLog(#"%d", [indexPath section]);
if ([indexPath section] == 0) {
cell.detailTextLabel.text = [separatedString objectAtIndex:indexPath.row];
}
return cell;
}
I'm just wondering just what is the best way to keep the text in my UITextView when the user scrolls the uitextview off the screen and back again?
update
- (UITableViewCell*) CreateMultilinesCell :(NSString*)cellIdentifier
{
//NSLog(#"Entering CreateMultilinesCell");
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:cellIdentifier] autorelease];
cell.detailTextLabel.numberOfLines = 0;
cell.detailTextLabel.font = [self SubFont];
cell.detailTextLabel.textColor = [UIColor colorWithRed:10.0/255 green:10.0/255 blue:33.0/255 alpha:1.0];
[cell setBackgroundColor:[UIColor clearColor]];//]colorWithRed:.98 green:.98 blue:.99 alpha:1.0]];
[self.tableView setBackgroundColor:[UIColor clearColor]];//colorWithRed:.94 green:.96 blue:.99 alpha:1.0]];
//NSLog(#"Exiting CreateMultilinesCell");
return cell;
}
The easiest solution is to use a different cell identifier for the two types of cells.
Edit: I see you are using two different types, but you are not taking that into account in the dequeue call.

Resources