I am trying to achieve a UITableView with cells and textfields but the cells keep on overlapping and textfields are jumping from one section to another.
Can someone please check my code for any mistake that I have done?
listForItemsinfo =[[NSArray alloc]initWithObjects:#"Name",#"Price", nil];
listForBrandYear =[[NSArray alloc] initWithObjects:#"Year",#"Alfa",#"aston",#"audi",#"bentley",#"BMW",#"Cadillac",#"Chevrolet",#"Ferrari",#"Ford",#"Jaguar",#"Jeep",#"Kia",#"Landrover",#"Mazda",#"Mercedes",#"Mitsubishi",#"Nissan",#"Porshe",#"Subaru", nil];
listForkeywords =[[NSArray alloc] initWithObjects:#"KeyWord1",#"Keyword2", nil];
listForcarType =[[NSArray alloc] initWithObjects:#"Sedan",#"Convertible",#"Coupe",#"Heatchback", nil];
listForItemsCategory =[[NSArray alloc] initWithObjects:#"cat1",#"cat2",#"cat3",#"cat4",#"cat5",#"cat6", nil];
sections = [[NSArray alloc]initWithObjects:#"Item's info",#"Brand, Year",#"Keywords",#"Car Type",#"Category", nil];
listOfsections =[[NSArray alloc]initWithObjects:listForItemsinfo,listForBrandYear,listForkeywords,listForcarType,listForItemsCategory, nil];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
if (indexPath.section == 0) {
// Add a UITextField
UITextField *textField = [[UITextField alloc] init];
// Set a unique tag on each text field
textField.tag = 1+ indexPath.row;
// Add general UITextAttributes if necessary
textField.enablesReturnKeyAutomatically = YES;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
[cell.contentView addSubview:textField];
}else if (indexPath.section == 1 ){
if (indexPath.row==0) {
UITextField *textField = [[UITextField alloc] init];
// Set a unique tag on each text field
textField.tag = 2+ indexPath.row;
// Add general UITextAttributes if necessary
textField.enablesReturnKeyAutomatically = YES;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
[cell.contentView addSubview:textField];
}
}else if (indexPath.section == 2 ){
if (indexPath.row==0 | indexPath.row ==1) {
UITextField *textField = [[UITextField alloc] init];
// Set a unique tag on each text field
textField.tag = 3+ indexPath.row;
// Add general UITextAttributes if necessary
textField.enablesReturnKeyAutomatically = YES;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
[cell.contentView addSubview:textField];
}else{
}
}
}
//cell.textLabel.text=#"wqewq";
//cell.textLabel.text = [[listOfsections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)theCell atIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
// Get the text field using the tag
UITextField *textField = (UITextField *)[theCell.contentView viewWithTag:1+indexPath.row];
// Position the text field within the cell bounds
CGRect cellBounds = theCell.bounds;
CGFloat textFieldBorder = 10.f;
// Don't align the field exactly in the vertical middle, as the text
// is not actually in the middle of the field.
CGRect aRect = CGRectMake(textFieldBorder, 9.f, CGRectGetWidth(cellBounds)-(2*textFieldBorder), 31.f );
textField.frame = aRect;
theCell.textLabel.text = NULL;
// Configure UITextAttributes for each field
if(indexPath.section == 0 & indexPath.row == 0) {
textField.placeholder = #"Name";
textField.returnKeyType = UIReturnKeyNext;
textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
} else if(indexPath.section == 0 & indexPath.row == 1) {
textField.placeholder = #"Price";
textField.returnKeyType = UIReturnKeyNext;
textField.keyboardType = UIKeyboardTypeNumberPad;
}else if (indexPath.section ==0 & indexPath.row >1){
[textField removeFromSuperview];
}
}else if (indexPath.section == 1) {
// Get the text field using the tag
UITextField *textField = (UITextField *)[theCell.contentView viewWithTag:2+indexPath.row];
// Position the text field within the cell bounds
CGRect cellBounds = theCell.bounds;
CGFloat textFieldBorder = 10.f;
// Don't align the field exactly in the vertical middle, as the text
// is not actually in the middle of the field.
CGRect aRect = CGRectMake(textFieldBorder, 9.f, CGRectGetWidth(cellBounds)-(2*textFieldBorder), 31.f );
textField.frame = aRect;
// Configure UITextAttributes for each field
if(indexPath.section == 1 & indexPath.row == 0) {
textField.placeholder = #"Year";
textField.returnKeyType =UIReturnKeyDone;
textField.autocapitalizationType = UIKeyboardTypeNumberPad;
theCell.textLabel.text = NULL;
}else if(indexPath.section == 1 & indexPath.row != 0){
[textField removeFromSuperview];
theCell.textLabel.text = [[listOfsections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
}
}else if (indexPath.section == 2) {
// Get the text field using the tag
UITextField *textField = (UITextField *)[theCell.contentView viewWithTag:3+indexPath.row];
// Position the text field within the cell bounds
CGRect cellBounds = theCell.bounds;
CGFloat textFieldBorder = 10.f;
// Don't align the field exactly in the vertical middle, as the text
// is not actually in the middle of the field.
CGRect aRect = CGRectMake(textFieldBorder, 9.f, CGRectGetWidth(cellBounds)-(2*textFieldBorder), 31.f );
textField.frame = aRect;
// Configure UITextAttributes for each field
if(indexPath.section == 2 & indexPath.row == 0) {
textField.placeholder = #"Keyword1";
textField.returnKeyType =UIReturnKeyDone;
textField.autocapitalizationType = UIKeyboardTypeNumberPad;
}else if(indexPath.section == 2 & indexPath.row == 1) {
textField.placeholder = #"Keyword2";
textField.returnKeyType =UIReturnKeyDone;
textField.autocapitalizationType = UIKeyboardTypeNumberPad;
}else{}
}
}
FIXED ! if anyone has the same problem (working code)
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Add a UITextField
UITextField *textField = [[UITextField alloc] init];
// Set a unique tag on each text field
textField.tag = 1 + indexPath.row;
textField.delegate=self;
// Add general UITextAttributes if necessary
textField.enablesReturnKeyAutomatically = YES;
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
// Position the text field within the cell bounds
CGRect cellBounds = cell.bounds;
CGFloat textFieldBorder = 10.f;
// Don't align the field exactly in the vertical middle, as the text
// is not actually in the middle of the field.
CGRect aRect = CGRectMake(textFieldBorder, 9.f, CGRectGetWidth(cellBounds)-(2*textFieldBorder), 31.f );
textField.frame = aRect;
textField.placeholder = #"Search for an item";
textField.returnKeyType = UIReturnKeyDefault;
textField.autocapitalizationType = UITextAutocapitalizationTypeWords;
if ((indexPath.section == 0) & (indexPath.row==0)) {
[cell.contentView addSubview:textField];
cell.textLabel.text=NULL;
}else{
[textField removeFromSuperview];
cell.textLabel.text = [[sections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
}
The table won't make cells overlap, but cells do get reused. Your problem is that your only configuring the cell when you initialize it. In fact, you need to do that configuration whether you create a new cell or get an old one from -dequeueReusableCellWithIdentifier:.
Perhaps you were thinking that a table view saves every cell that you give it? That's not how it works... Reusable cells mean that a table only needs about as many cells as can be displayed at once. As you scroll the view, the cells that scroll off the top or bottom are recycled as new cells for new content. You're not setting the new content, though, so the old content shows up instead.
Add a close bracket after the first line of your if, so that the rest of the code is always executed:
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.section == 0) {
Related
I am setting an UILabel inside of the cellForRowAtIndexPath method and when the user changes the text, the label should change. But even it is not nil, it doesn't change.
#property UILabel *myLabel;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
self.myLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, textView.frame.size.width, 37)];
self.myLabel.text = #"Old Text";
}
- (void)textViewDidChange:(UITextView *)textView {
self.myLabel.textColor = [UIColor redColor];
self.myLabel.text = #"New Text";
}
I found a solution where some people are changing the UILabel in the main thread but that's not working for me.
dispatch_async(dispatch_get_main_queue(), ^{
// Do in main thread
});
If you want to modify the label of a cell that's on-screen "on the fly" then you need a way to reach the label.
What I usually do is to create a template for the cell in IB, define a custom subclass of UITableViewCell, and set the cell's class to that custom subclass. Then I connect outlets between the cell and all the custom fields I've created.
In my cellForRowAtIndexPath method, I dequeue a cell and cast it to my custom type. Then I reference the fields in the cell through the cell, e.g.
cell.myLabel.
If you add a new field to your cell in cellForRowAtIndexPath you have a couple of problems. First, you need to make sure you don't add another copy of that new field when you recycle the cell. Second, you need a way to get to the field if you want to modify it, as in your question. There are ways to deal with these problems, but the approach I outlined above is cleaner.
Duncan, I'm sorry, here is the rest of the cellForRowAtIndexPath. I thought it could not be a problem of reusing the cell as I'm not scrolling so the cell should not be recreated.
#property NSString *textField_1;
#property NSString *textField_2;
// ...
#property UILabel *myLabel;
#end
#implementation TableViewController
- (void)textViewDidChange:(UITextView *)textView
{
self.myLabel.textColor = [UIColor redColor];
self.myLabel.text = #"New Text";
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
if(indexPath.section == 0)
{
float displayResolutionWidth = self.view.frame.size.width;
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 0, displayResolutionWidth - 165, 50)];
textField.delegate = self;
textField.tag = indexPath.row;
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
UITextView *textView = [[UITextView alloc]initWithFrame:CGRectMake(0, 0, displayResolutionWidth - 90, 176)];
textView.delegate = self;
textView.tag = indexPath.row;
textView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.myLabel = [[UILabel alloc] initWithFrame:CGRectMake(5, 0, textView.frame.size.width, 37)];
self.myLabel.textColor = [UIColor redColor];
if(indexPath.row == 17)
{
cell.accessoryView = textView;
[textView addSubview:self.myLabel];
}
else if (indexPath.row != 17)
{
cell.accessoryView = textField;
}
if (self.object)
{
if (indexPath.row == 0)
textField.text = self.object.property_1;
if (indexPath.row == 1)
textField.text = self.object.property_2;
}
else if (!self.object)
{
if (indexPath.row == 0)
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:NSLocalizedString(#"Placeholder_1", #"")
attributes:#{NSForegroundColorAttributeName: [UIColor greenColor]}];
if (indexPath.row == 1)
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:NSLocalizedString(#"Placeholder_2", #"")
attributes:#{NSForegroundColorAttributeName: [UIColor greenColor]}];
if (indexPath.row == 17)
self.myLabel.text = "Old Text";
}
if (indexPath.row != 17)
{
cell.textLabel.text = [self.arrayWithObjectData objectAtIndex:indexPath.row];
}
else if (indexPath.row == 17)
{
UILabel *mylabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 0, 150, 40)];
mylabel.text = self.arrayWithObjectData[17];
mylabel.textColor = [UIColor COLOR_TEXT];
[cell.contentView addSubview:mylabel];
}
}
return cell;
}
#end
I have created an table view shown in landscape orientation.
I want to add multiple text fields dynamically to table cell and also want to get data can any one suggest me. How can I scroll it horizontally in iOS?
UITextField *mytextField = [[UITextField alloc]initWithFrame:CGRectMake(110, 10, 185, 30)];
mytextField.clearsOnBeginEditing = NO;
mytextField.textAlignment = UITextAlignmentRight;
mytextField.delegate = self;
[yourCell.contentView addSubview: mytextField];
or
try 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:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row == 0){
21)];
self.mytextField1 = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.mytextField1.placeholder = #"mytextField1";
self.mytextField1.autocorrectionType = UITextAutocorrectionTypeNo;
[self.mytextField1 setClearButtonMode:UITextFieldViewModeWhileEditing];
[cell addSubview:self.mytextField1];
}
if (indexPath.row == 1){
self.mytextField2 = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
self.mytextField2.placeholder = #"mytextField2";
self.mytextField2.autocorrectionType = UITextAutocorrectionTypeNo;
[self.mytextField2 setClearButtonMode:UITextFieldViewModeWhileEditing];
[cell addSubview:self.mytextField2];
}
if (indexPath.row == 2){
// add here
}
if (indexPath.row == 3){
}
self.mytextField1.delegate = self;
self.mytextField2.delegate = self;
// and other also here
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Instead of adding textField directly into tableCell you can first add a scroll view on tableCell than add multiple textField on this scroll view. Set the content size accordingly of scroll view, so that it will scroll easily to the end.
In my UITableView I am trying to display all the items in my plist but its not showing all the items. Actually it is showing most of it but the lower items are being repeated for some odd reason. I basically want to show all the keys in the plist with their respective values. Is the list too long to display? there's about 30 items.
First I tried to sort the keys and thought that was the problem, so then I didn't sort at all and I get the same problem, lower down the list the items get repeated and not showing the last 3 items. Is there a limit?
Below is some code, I've just modified to fit:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"PreferencesCell1";
static NSString *CellIdentifier2 = #"PreferencesCell2";
static NSString *CellIdentifier3 = #"PreferencesCell3";
UITableViewCell *cell;
NSArray *keys = [[[preferences objectAtIndex:indexPath.section] objectForKey:#"Rows"] allKeys];
NSString *prefName = [keys objectAtIndex:indexPath.row];
if (indexPath.section == 0 || indexPath.section == 2) {
if(indexPath.section == 0)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
else if(indexPath.section == 2)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
if(indexPath.section == 0)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
else if(indexPath.section == 2)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *settingName = [[UILabel alloc] initWithFrame:labelRect];
settingName.font = [UIFont boldSystemFontOfSize:17.0];
settingName.backgroundColor = [UIColor clearColor];
settingName.text = prefName;
[cell.contentView addSubview: settingName];
[settingName release];
}
} else if(indexPath.section == 1) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier3];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier3] autorelease];
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *label = [[UILabel alloc] initWithFrame:labelRect];
label.font = [UIFont boldSystemFontOfSize:17.0];
label.backgroundColor = [UIColor clearColor];
label.text = prefName;
[cell.contentView addSubview: label];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
What I've found is that if I don't use the labels and just go for the generic cell.textLabel.text approach then all the items are displayed correctly. However if I use the UILabel approach, the bottom items are not shown. I need to go this route as I'm adding other items in the Cell.
Working Code.
Initialization and creation of cell must be created first, then using that referenced cell remove from superview, then render the subviews. So reordering of the code from above.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"PreferencesCell1";
static NSString *CellIdentifier2 = #"PreferencesCell2";
static NSString *CellIdentifier3 = #"PreferencesCell3";
UITableViewCell *cell;
NSArray *keys = [[[preferences objectAtIndex:indexPath.section] objectForKey:#"Rows"] allKeys];
NSString *prefName = [keys objectAtIndex:indexPath.row];
// Create/Initialize Cell first
if (indexPath.section == 0 || indexPath.section == 2) {
if(indexPath.section == 0)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
else if(indexPath.section == 2)
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
if(indexPath.section == 0)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
else if(indexPath.section == 2)
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2] autorelease];
}
} else if(indexPath.section == 1) {
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier3];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier3] autorelease];
}
}
// remove from superview
[cell.contentView.subviews makeObjectsPerformSelector:#selector(removeFromSuperview)];
// render the subviews
if (indexPath.section == 0 || indexPath.section == 2) {
cell.accessoryType = UITableViewCellAccessoryNone;
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *settingName = [[UILabel alloc] initWithFrame:labelRect];
settingName.font = [UIFont boldSystemFontOfSize:17.0];
settingName.backgroundColor = [UIColor clearColor];
settingName.text = prefName;
[cell.contentView addSubview: settingName];
[settingName release];
} else if(indexPath.section == 1) {
CGRect labelRect = CGRectMake(10, 5, 300, 31);
UILabel *label = [[UILabel alloc] initWithFrame:labelRect];
label.font = [UIFont boldSystemFontOfSize:17.0];
label.backgroundColor = [UIColor clearColor];
label.text = prefName;
[cell.contentView addSubview: label];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
return cell;
}
It looks like cells are being reused and you are just adding new views to their existing contents. You need to reset the content, as described here: UITbleViewCell Class Reference. If you were just setting the cell's textLabel each time, setting a new value would suffice here, but if you are adding subviews you may need something more like [cell.contentView.subviews makeObjectsPerformSelector: #selector(removeFromSuperview)];
The Limit for a Tableview is the free RAM size.
Please post some Code. But i think that this could be a Problem with Cell caching.
I add in a UiTableViewCell a UITextField *gasPrice; like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier;
if (indexPath.section == 0 && indexPath.row < [self.userCarsArray count])
CellIdentifier = [NSString stringWithFormat:#"Cell%d%d%#", indexPath.section, indexPath.row, [[self.userCarsArray objectAtIndex:indexPath.row] idCar]];
else if (indexPath.section == 0 && indexPath.row == [self.userCarsArray count])
CellIdentifier = [NSString stringWithFormat:#"Cell%d%d%#", indexPath.section, indexPath.row, #"AddCar"];
else
CellIdentifier = [NSString stringWithFormat:#"Cell%d%d", indexPath.section, indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
if (indexPath.section == 1 && indexPath.row == 0) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
else if (indexPath.section == 2 && indexPath.row == 2) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier] autorelease];
}
else {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
if (indexPath.section == 1 && indexPath.row == 1) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(170, 10, 125, 30)];
textField.adjustsFontSizeToFitWidth = YES;
textField.textColor = [UIColor colorWithRed:0.20f green:0.30f blue:0.49f alpha:1.0f];
textField.placeholder = #"0.00";
textField.keyboardType = UIKeyboardTypeDecimalPad;
textField.returnKeyType = UIReturnKeyDone;
textField.backgroundColor = [UIColor whiteColor];
textField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textField.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textField.textAlignment = UITextAlignmentRight;
textField.tag = 0;
textField.delegate = self;
textField.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textField setEnabled: YES];
[cell addSubview:textField];
[textField release];
gasField = textField;
}
}
// Selection style.
cell.selectionStyle = UITableViewCellSelectionStyleGray;
// Vehicles cells.
if (indexPath.section == 0) {
// ...
}
// General cells.
if (indexPath.section == 1) {
if (indexPath.row == 0) {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.textLabel.text = #"Measurement System";
cell.textLabel.textColor = [UIColor darkGrayColor];
if ([EcoAppAppDelegate measurement] == MeasurementTypeMile)
cell.detailTextLabel.text = #"Miles";
else
cell.detailTextLabel.text = #"Meters";
}
if (indexPath.row == 1) {
cell.textLabel.textColor = [UIColor darkGrayColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if ([EcoAppAppDelegate measurement] == MeasurementTypeMile)
cell.textLabel.text = #"Gas Price (gal)";
else
cell.textLabel.text = #"Gas Price (L)";
// Gas price.
if ([EcoAppAppDelegate gasPrice] != 0.00)
gasField.text = [NSString stringWithFormat:#"%.2f", [EcoAppAppDelegate gasPrice]];
}
}
// Information cells.
if (indexPath.section == 2) {
// ...
}
return cell;
}
Then, to manage the keyboard when the user is done (because I use a keyboard without return key), I have those functions:
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
UIBarButtonItem *doneButton = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(done:)] autorelease];
[self.navigationItem setLeftBarButtonItem:doneButton animated:YES];
return YES;
}
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
// Save gas price.
if ([textField.text isEqualToString:#""])
[EcoAppAppDelegate setGasPrice:0.00];
else
[EcoAppAppDelegate setGasPrice:[textField.text floatValue]];
return YES;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
// Hide keyboard.
[textField resignFirstResponder];
return YES;
}
And the function for the navigation bar button "Done":
- (void)done:(id)sender {
if ([gasField canResignFirstResponder]) {
[gasField resignFirstResponder];
}
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
}
So it works fine first, when I stay in my settings view controller, but when I do other stuff on some other cells (that push other view controllers, come back, etc), it stops working. It is probably because the gasField pointer has disappeared or something like that, the gasField object tho is still different from nil.
Any idea why it does that? Thanks!
I think you are using gasField as a property. use
self.gasField
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.