I've been banging my head against the wall on this one for quite some time now. Any input or direction is greatly appreciated.
So the goal is the create a log in form from text fields in a table. That user info, once collected will be passed on to an array in a seperate view controller so in can stored in a "favourites" list.
So I've created the form which looks great and all but when I console out the form results the fields are return (null). I've picked the site for answers but can't anything exact. Below is the cellForRowAtIndexPath: method I feel that maybe the issue is where I'm creating the textFields. Again, any input is appreciated!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
NSArray *listData =[self.tableContents objectForKey:[self.sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
reuseIdentifier:CellIdentifier] autorelease];
textField = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
[textField retain];
}
textField.adjustsFontSizeToFitWidth = NO;
textField.font = [UIFont fontWithName:#"Helvetica" size:14.0];
textField.textColor = [UIColor darkGrayColor];
textField.returnKeyType = UIReturnKeyDone;
textField.backgroundColor = [UIColor clearColor];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.textAlignment = UITextAlignmentLeft;
textField.clearButtonMode = UITextFieldViewModeNever;
textField.delegate = self;
if ([indexPath section] == 0) {
switch (indexPath.row) {
case 0:
textField.placeholder = #"Optional";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
textField.tag = 0;
break;
case 1:
textField.placeholder = #"";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
textField.tag = 1;
break;
case 2:
textField.placeholder = #"";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
textField.tag = 2;
break;
case 3:
textField.placeholder = #"";
textField.secureTextEntry = YES;
textField.keyboardType = UIKeyboardTypeDefault;
textField.tag = 3;
break;
case 4:
textField.placeholder = #"Optional";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
textField.tag = 4;
break;
case 5:
textField.placeholder = #"Optional";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeNumberPad;
textField.tag = 5;
break;
}
}
[textField setEnabled: YES];
[cell addSubview:textField];
cell.textLabel.text = [listData objectAtIndex:indexPath.row];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryType = UITableViewCellAccessoryNone;
cell.editing = YES;
return cell;
}
The textField variable (I assume it is an ivar in the class or a static global variable) is your main problem. You create a new text field each time you create a new cell, which is fine, but then you add it to a cell every time the cellForRowAtIndexPath method is called. Since cells are reused this will screw things up.
Your code need to look something like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
NSArray *listData =[self.tableContents objectForKey:[self.sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:CellIdentifier] autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.accessoryType = UITableViewCellAccessoryNone;
cell.editing = YES;
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(120, 13, 375, 30)];
textfield.tag = 1;
textField.adjustsFontSizeToFitWidth = NO;
textField.font = [UIFont fontWithName:#"Helvetica" size:14.0];
textField.textColor = [UIColor darkGrayColor];
textField.returnKeyType = UIReturnKeyDone;
textField.backgroundColor = [UIColor clearColor];
textField.autocorrectionType = UITextAutocorrectionTypeNo;
textField.autocapitalizationType = UITextAutocapitalizationTypeNone;
textField.textAlignment = UITextAlignmentLeft;
textField.clearButtonMode = UITextFieldViewModeNever;
textField.delegate = self;
[textField setEnabled: YES];
[cell.contentView addSubview:textField];
[textField release];
}
UITextField *textField = (UITextField *) [cell.contentView viewWithTag:1];
if ([indexPath section] == 0) {
switch (indexPath.row) {
case 0:
textField.placeholder = #"Optional";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
break;
case 1:
textField.placeholder = #"";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
break;
case 2:
textField.placeholder = #"";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
break;
case 3:
textField.placeholder = #"";
textField.secureTextEntry = YES;
textField.keyboardType = UIKeyboardTypeDefault;
break;
case 4:
textField.placeholder = #"Optional";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeDefault;
break;
case 5:
textField.placeholder = #"Optional";
textField.secureTextEntry = NO;
textField.keyboardType = UIKeyboardTypeNumberPad;
break;
}
}
textField.text = [listData objectAtIndex:indexPath.row];
return cell;
}
Not sure this does exactly what you want but it should point you in the right direction.
Create a custom cell to place your text field, for the love of god. You shouldn't have addSubview: related code in your tableView:cellForRowAtIndexPath:; just code that allocates the cell, and configures the cell enough so that the cell itself can display things they way you want them.
Look at the table view suite for an example of how to use custom cells. I believe 4_ and 5_ have custom cells.
Related
I have a UITextField in a UITableViewCell.
Even though I set -
textField.userInteractionEnabled = NO;
textField.enabled = NO
But when I click on the table cell which contains the textField, the keyboard comes up for the textfield.
Why is this happening and how can I prevent it?
EDIT: Strangely this is happening when I first set some text in the textfield. When the textfield is empty, it is not editable.
EDIT: Code for cellForRowAtIndexPath -
cell = [tableView dequeueReusableCellWithIdentifier:#"CellIdentifier"];
cell.accessoryType = UITableViewCellAccessoryNone;
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, cell.bounds.size.width - 20, cell.bounds.size.height - 20)];
textField.font = [UIFont systemFontOfSize:15];
textField.textColor = [UIColor blackColor];
UIColor *placeholderColor = [UIColor colorWithRed:146/255.0 green:146/255.0 blue:146/255.0 alpha:1];
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:[self getPlaceHolderTextForIndexPath:indexPath] attributes:#{NSForegroundColorAttributeName : placeholderColor}];
textField.keyboardType = [self getKeyboardTyeForIndexPath:indexPath];
textField.returnKeyType = UIReturnKeyDone;
textField.backgroundColor = [UIColor clearColor];
textField.textAlignment = NSTextAlignmentLeft;
textField.autocapitalizationType = [self getAutocapitaliztionTypeForIndexPath:indexPath];
textField.tag = 1;
if (_editingNotAllowed) {
[textField setText:[self getTextForTextFieldWithIndexPath:indexPath]];
[textField setUserInteractionEnabled:NO];
textField.enabled = NO;
} else {
[textField setUserInteractionEnabled:YES];
}
[cell.contentView addSubview:textField];
You should create an UITableViewCell as shown in this repo :)
https://github.com/breeno/EditingUITableView
And use your custom UITableViewCell like this:
if(condition){ // Check the row must be TextField
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier: nil];
if(!cell){
cell = [[CustomCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: nil];
}
cell.label.text = #"Title Row"; //UITextLabel Title
UIColor *placeholderColor = [UIColor colorWithRed:146/255.0 green:146/255.0 blue:146/255.0 alpha:1];
cell.textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:[self getPlaceHolderTextForIndexPath:indexPath] attributes:#{NSForegroundColorAttributeName : placeholderColor}];
cell.textField.returnKeyType = UIReturnKeyDone;
cell.textField.backgroundColor = [UIColor clearColor];
cell.textField.textAlignment = NSTextAlignmentLeft;
cell.textField.tag = 1;
} else { // Normal UITableViewCell
}
I've got a little problem with my UITableViewCells.
I've got 5 sections with different amount of rows in my tableView. I added each row a subview including a UITextfield. the problem i am having is, that when i scroll, my subviews of the cell are changing around. I took a video, so you can see what i mean.
http://files.beger.org/Scolling_Issue18072012.swf
Sorry that it is all in german :)
here is the 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];
// Add a UITextFiel
if ([indexPath section] == 0) {
UITextField *textFieldName = [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 185, 30)];
textFieldName.adjustsFontSizeToFitWidth = YES;
textFieldName.textColor = [UIColor blackColor];
if ([indexPath row] == 0) {
textFieldName.placeholder = #"Max";
textFieldName.keyboardType = UIKeyboardTypeDefault;
textFieldName.returnKeyType = UIReturnKeyDone;
}
else {
textFieldName.placeholder = #"Mustermann";
textFieldName.keyboardType = UIKeyboardTypeDefault;
textFieldName.returnKeyType = UIReturnKeyDone;
}
textFieldName.backgroundColor = [UIColor clearColor];
textFieldName.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textFieldName.autocapitalizationType = UITextAutocapitalizationTypeWords; // no auto capitalization support
textFieldName.textAlignment = UITextAlignmentLeft;
textFieldName.tag = 0;
//playerTextField.delegate = self;
textFieldName.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textFieldName setEnabled: YES];
[cell addSubview:textFieldName];
[textFieldName release];
}
else if ([indexPath section] == 1) {
UITextField *textFieldContactData = [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 185, 30)];
textFieldContactData.adjustsFontSizeToFitWidth = YES;
textFieldContactData.textColor = [UIColor blackColor];
if ([indexPath row] == 0) {
textFieldContactData.placeholder = #"04132 21123 321";
textFieldContactData.keyboardType = UIKeyboardTypePhonePad;
}
else if ([indexPath row] == 1) {
textFieldContactData.placeholder = #"04132 21123 300";
textFieldContactData.keyboardType = UIKeyboardTypePhonePad;
}
else if ([indexPath row] == 2) {
textFieldContactData.placeholder = #"0150 12543 101";
textFieldContactData.keyboardType = UIKeyboardTypePhonePad;
}
else if ([indexPath row] == 3) {
textFieldContactData.placeholder = #"beispiel#musterfirma.de";
textFieldContactData.keyboardType = UIKeyboardTypeEmailAddress;
textFieldContactData.returnKeyType = UIReturnKeyDone;
}
else if ([indexPath row] == 4) {
textFieldContactData.placeholder = #"www.musterfirma.de";
textFieldContactData.keyboardType = UIKeyboardTypeURL;
textFieldContactData.returnKeyType = UIReturnKeyDone;
}
else {
textFieldContactData.placeholder = #"Deutsch";
textFieldContactData.keyboardType = UIKeyboardTypeDefault;
textFieldContactData.returnKeyType = UIReturnKeyDone;
}
textFieldContactData.backgroundColor = [UIColor clearColor];
textFieldContactData.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textFieldContactData.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textFieldContactData.textAlignment = UITextAlignmentLeft;
textFieldContactData.tag = 0;
//playerTextField.delegate = self;
textFieldContactData.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textFieldContactData setEnabled: YES];
[cell addSubview:textFieldContactData];
[textFieldContactData release];
}
// Adresse
else if ([indexPath section] == 2) {
UITextField *textFieldAddress = [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 185, 30)];
textFieldAddress.adjustsFontSizeToFitWidth = YES;
textFieldAddress.textColor = [UIColor blackColor];
if ([indexPath row] == 0) {
textFieldAddress.placeholder = #"Musterstr. 10";
textFieldAddress.keyboardType = UIKeyboardTypeDefault;
textFieldAddress.autocapitalizationType = UITextAutocapitalizationTypeWords;
}
else if ([indexPath row] == 1) {
textFieldAddress.placeholder = #"50000";
textFieldAddress.keyboardType = UIKeyboardTypeDefault;
}
else if ([indexPath row] == 2) {
textFieldAddress.placeholder = #"Musterstadt";
textFieldAddress.keyboardType = UIKeyboardTypeDefault;
textFieldAddress.autocapitalizationType = UITextAutocapitalizationTypeWords;
}
else {
textFieldAddress.placeholder = #"Deutschland";
textFieldAddress.keyboardType = UIKeyboardTypeDefault;
textFieldAddress.autocapitalizationType = UITextAutocapitalizationTypeWords;
}
textFieldAddress.backgroundColor = [UIColor clearColor];
textFieldAddress.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textFieldAddress.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textFieldAddress.textAlignment = UITextAlignmentLeft;
textFieldAddress.tag = 0;
//playerTextField.delegate = self;
textFieldAddress.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textFieldAddress setEnabled: YES];
[cell addSubview:textFieldAddress];
[textFieldAddress release];
}
// Abteilung und Funktion
else if ([indexPath section] == 3) {
UITextField *textFieldFunction = [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 185, 30)];
textFieldFunction.adjustsFontSizeToFitWidth = YES;
textFieldFunction.textColor = [UIColor blackColor];
if ([indexPath row] == 0) {
textFieldFunction.placeholder = #"Einkauf";
textFieldFunction.keyboardType = UIKeyboardTypeDefault;
textFieldFunction.autocapitalizationType = UITextAutocapitalizationTypeWords;
}
else {
textFieldFunction.placeholder = #"Einkaufsleiter";
textFieldFunction.keyboardType = UIKeyboardTypeDefault;
textFieldFunction.autocapitalizationType = UITextAutocapitalizationTypeWords;
}
textFieldFunction.backgroundColor = [UIColor clearColor];
textFieldFunction.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textFieldFunction.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textFieldFunction.textAlignment = UITextAlignmentLeft;
textFieldFunction.tag = 0;
//playerTextField.delegate = self;
textFieldFunction.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textFieldFunction setEnabled: YES];
[cell addSubview:textFieldFunction];
[textFieldFunction release];
}
// Kundenbeziehung
else if ([indexPath section] == 4) {
UITextField *textFieldCustomer= [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 185, 30)];
textFieldCustomer.adjustsFontSizeToFitWidth = YES;
textFieldCustomer.textColor = [UIColor blackColor];
textFieldCustomer.placeholder = #"Musterfirma AG";
textFieldCustomer.keyboardType = UIKeyboardTypeDefault;
textFieldCustomer.backgroundColor = [UIColor clearColor];
textFieldCustomer.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textFieldCustomer.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textFieldCustomer.textAlignment = UITextAlignmentLeft;
textFieldCustomer.tag = 0;
textFieldCustomer.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textFieldCustomer setEnabled: YES];
[cell addSubview:textFieldCustomer];
[textFieldCustomer release];
}
// Lieferantenbeziehung
else {
UITextField *textFieldSupplier= [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 185, 30)];
textFieldSupplier.adjustsFontSizeToFitWidth = YES;
textFieldSupplier.textColor = [UIColor blackColor];
textFieldSupplier.placeholder = #"Lieferanten AG";
textFieldSupplier.keyboardType = UIKeyboardTypeDefault;
textFieldSupplier.backgroundColor = [UIColor clearColor];
textFieldSupplier.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textFieldSupplier.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textFieldSupplier.textAlignment = UITextAlignmentLeft;
textFieldSupplier.tag = 0;
textFieldSupplier.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textFieldSupplier setEnabled: YES];
[cell addSubview:textFieldSupplier];
[textFieldSupplier release];
}
}
if ([indexPath section] == 0) {
if ([indexPath row] == 0) {
// Vorname
cell.textLabel.text = #"Vorname";
}
else {
// Nachname
cell.textLabel.text = #"Nachname";
}
}
// Kontaktdaten
else if ([indexPath section] == 1) {
if ([indexPath row] == 0) {
cell.textLabel.text = #"Telefon";
}
else if ([indexPath row] == 1) {
cell.textLabel.text = #"Fax";
}
else if ([indexPath row] == 2) {
cell.textLabel.text = #"Mobil";
}
else if ([indexPath row] == 3) {
cell.textLabel.text = #"E-Mail";
}
else if ([indexPath row] == 4) {
cell.textLabel.text = #"WWW";
}
else {
cell.textLabel.text = #"Sprache";
}
}
// Adresse
else if ([indexPath section] == 2) {
if ([indexPath row] == 0) {
cell.textLabel.text = #"Straße";
}
else if ([indexPath row] == 1) {
cell.textLabel.text = #"PLZ";
}
else if ([indexPath row] == 2) {
cell.textLabel.text = #"Ort";
}
else {
cell.textLabel.text = #"Land";
}
}
// Section Abteilung und Funktion
else if ([indexPath section] == 3) {
if ([indexPath row] == 0) {
cell.textLabel.text = #"Abteilung";
}
else {
cell.textLabel.text = #"Funktion";
}
}
// Section Kundenbeziehung
else if ([indexPath section] == 4) {
cell.textLabel.text = #"Kunde";
}
// Section Lieferantenbeziehung
else {
cell.textLabel.text = #"Lieferant";
}
return cell;
}
I think the cells can not store my data/subviews when i reuse them.
Is there any way to solve the problem?
Thanks!
Christoph
dequeueReusableCellWithIdentifier returns you reusable cell, if any. It means if some cell is not visible, iOS will not create a UITableViewCell again. It will directly return used cell. It makes performance better and memory utilization low.
So, when you identify cell is nil, you should create a cell and textfield. Add the textfiled as a subview of a cell.
Outside of cell is nil, you should provide other attributes of textfiled. You have done same thing for cell.textLable.text. You need to carry same exercise for textfiled also. To fetch the textField, tag while adding. Using that tag, you can fetch textField back.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
// Add a UITextFiel
if ([indexPath section] == 0) {
UITextField *textFieldName = [[UITextField alloc] initWithFrame:CGRectMake(120, 10, 185, 30)];
textFieldName.adjustsFontSizeToFitWidth = YES;
textFieldName.textColor = [UIColor blackColor];
textFieldName.tag = 25;
if ([indexPath row] == 0) {
textFieldName.placeholder = #"Max";
textFieldName.keyboardType = UIKeyboardTypeDefault;
textFieldName.returnKeyType = UIReturnKeyDone;
textFieldName.backgroundColor = [UIColor clearColor];
textFieldName.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textFieldName.autocapitalizationType = UITextAutocapitalizationTypeWords; // no auto capitalization support
textFieldName.textAlignment = UITextAlignmentLeft;
[cell addSubview:textFieldName];
[textFieldName release];
}
}
}
//Here fetch the textFiled..
UITextFiled *tField = [cell viewWithTag:25];
//Identify row, section and do other operations like setting text, place holder etc...
You only add a UITextView if the cell is a newly created cell, so if the cell is re-used then the UITextview gets re-used as well. To get around this you could either:
Move all your UITextView creation code out of the if (cell == nil) statement
or
When you set the cell.textlabel.text find a way of accessing the textview thats already added to the cell (using the tag property, or looping through the subviews) and make changes to it.
Hope this helps.
I want a section of my table view to reload whenever the ViewWillAppear method is called, I've implemented this like so:
- (void)viewWillAppear:(BOOL)animated {
NSIndexPath* rowToReload = [NSIndexPath indexPathForRow:0 inSection:1];
reloadRows = [NSArray arrayWithObjects:rowToReload, nil];
[self.tableView reloadRowsAtIndexPaths:reloadRows withRowAnimation:UITableViewRowAnimationNone];
}
Here is the rowforsection method that indicates which content should appear in each tableview section:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"fadk");
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"PINGAS"];
[self.tableView setAlwaysBounceVertical:YES];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:#"PINGAS"] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
// if ([indexPath section] == 0) {
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10, 3, 300, 41)];
UITextView *textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 0, 300, 120)];
UIView *paddingView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 0)] autorelease];
paddingView.backgroundColor = [UIColor cyanColor];
// if ([indexPath row] == 0) {
if ([indexPath section] == 0) {
NSLog(#"0");
[cell addSubview:textField];
if ([indexPath row] == 0) {
textField.placeholder = #"Title";
}
else{
textField.placeholder = #"Location";
}
}
else if ([indexPath section] == 1) {
NSLog(#"1");
NSDateFormatter *formatter;
NSString *eSString1;
NSString *eEString2;
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"h:mm a"];
cell.textLabel.text = #"Starts\nEnds";
cell.textLabel.numberOfLines = 2;
eSString1 = [formatter stringFromDate:eSTime];
eEString2 = [formatter stringFromDate:eEtime];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#\n%#", eSString1, eEString2];
cell.detailTextLabel.numberOfLines = 2;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
else{
NSLog(#"2");
[cell addSubview:textView];
}
textField.delegate = self;
textField.leftView = paddingView;
textField.leftViewMode = UITextFieldViewModeAlways;
textField.adjustsFontSizeToFitWidth = YES;
textField.textColor = [UIColor blackColor];
textField.keyboardType = UIKeyboardTypeAlphabet;
textField.returnKeyType = UIReturnKeyDone;
textField.backgroundColor = [UIColor clearColor];
textField.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textField.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textField.textAlignment = UITextAlignmentLeft;
textField.tag = 0;
//playerTextField.delegate = self;
textField.clearButtonMode = UITextFieldViewModeNever; // no clear 'x' button to the right
[textField setEnabled: YES];
[textField release];
textView.delegate = self;
textView.textColor = [UIColor blackColor];
textView.keyboardType = UIKeyboardTypeAlphabet;
textView.returnKeyType = UIReturnKeyDone;
textView.backgroundColor = [UIColor clearColor];
textView.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
textView.autocapitalizationType = UITextAutocapitalizationTypeNone; // no auto capitalization support
textView.textAlignment = UITextAlignmentLeft;
textView.tag = 0;
[textView release];
// }
}
return cell;
}
This works swimmingly the first load, and I after the first calling of viewWillAppear, but after that the section seems to recycle the data from the first load and the second load, and while it still enters the cellforrow section, it no longer goes into the section I call in the viewWIllAppear section.
The reload should be sandwiched between begin / end updates:
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:reloadRows withRowAnimation:UITableViewRowAnimationNone];
[self.tableView endUpdates];
I have two views: the first one is a UITableView in plain style (created programmatically); the second one is a UIScrollView that contains an image and a UITableView in grouped style (also created programmatically).
When I navigate from the firstView -> secondView everything works fine. However if I come back to the firstView and then I try to navigate firstView ->secondView for the second time, I get a EXC_BAD_ACCESS error.
UPDATE
This is the code of the UITableView delegate in the secondView:
-
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch (section) {
case 0:
//header - breve descrizione
return 2;
break;
case 1: //mappa
//header - mappa statica (immagine) - footer (indirizzo)
return 3;
break;
case 2: //review
//header - prima review
return 2;
break;
default:
return 0;
break;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case 0:
switch (indexPath.row) {
case 0: //case titolo (header)
return HTABLE_DESCR_HEADER;
break;
case 1: //case corpo
return HTABLE_DESCR_BODY;
break;
default:
return 0;
break;
}
break;
case 1:
switch (indexPath.row) {
case 0: //case titolo (header)
return HTABLE_LOC_HEADER;
break;
case 1: //case corpo
return HTABLE_LOC_BODY;
break;
case 2: //case footer
return HTABLE_LOC_FOOTER;
break;
default:
return 0;
break;
}
break;
case 2:
switch (indexPath.row) {
case 0: //case titolo (header)
return HTABLE_REV_HEADER;
break;
case 1: //case corpo
return HTABLE_REV_BODY;
break;
default:
return 0;
break;
}
break;
default:
return 0;
break;
}
}
/*- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"Travellers Guide";
}*/
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
int section = 2;
//se ci sono review
if ([[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"list_review"] count] > 0) {
section++;
}
return section;
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [self getCellContentView:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleGray;
switch (indexPath.section) {
case 0: //descrizione
switch (indexPath.row) {
case 0: //header
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"language"] isEqualToString:#"it"]) {
cell.textLabel.text = #"Descrizione";
} else {
cell.textLabel.text = #"Description";
}
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.shadowColor = [UIColor whiteColor];
cell.textLabel.shadowOffset = CGSizeMake(1, 1);
cell.textLabel.highlightedTextColor = [UIColor blackColor];
cell.textLabel.font = [UIFont boldSystemFontOfSize:11.0];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"rigaDescrHeader.png"]];
break;
case 1: //descrizione
NSLog(#"Descr");
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"rigaRevBody.png"]];
cell.textLabel.text = [[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"description"];
cell.textLabel.font = [UIFont systemFontOfSize:10.0];
cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;
cell.textLabel.numberOfLines = 3;
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.shadowColor = [UIColor whiteColor];
cell.textLabel.shadowOffset =CGSizeMake(1, 1);
cell.textLabel.highlightedTextColor = [UIColor blackColor];
break;
default:
break;
}
break;
case 1: //mappa
//header - mappa statica (immagine) - footer (indirizzo)
switch (indexPath.row) {
case 0: //header
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"language"] isEqualToString:#"it"]) {
cell.textLabel.text = #"Posizione";
} else {
cell.textLabel.text = #"Location";
}
cell.textLabel.font = [UIFont boldSystemFontOfSize:11.0];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.shadowColor = [UIColor whiteColor];
cell.textLabel.shadowOffset = CGSizeMake(1, 1);
cell.textLabel.highlightedTextColor = [UIColor blackColor];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"rigaLocHeader.png"]];
break;
case 1: //mappa
NSLog(#"Mappa");
CLLocationDegrees latitude = [[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"latitude"] doubleValue];
CLLocationDegrees longitude = [[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"longitude"] doubleValue];
CLLocation* poiLocation = [[[CLLocation alloc] initWithLatitude:latitude longitude:longitude] autorelease];
Annotation *ann = [Annotation annotationWithCoordinate:poiLocation.coordinate];
//mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, HTABLE_LOC_BODY)];
[mapView setHidden:NO];
[mapView addAnnotation:ann];
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center = poiLocation.coordinate;
region.span.longitudeDelta = 0.05f;
region.span.latitudeDelta = 0.05f;
[self.mapView setRegion:region animated:YES];
[self.mapView regionThatFits:region];
cell.backgroundView = mapView;
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 302, 120)];
imgView.image = [UIImage imageNamed:#"ombraMappa.png"];
[cell.backgroundView addSubview:imgView];
[imgView release];
break;
case 2: //footer
cell.textLabel.text = [[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"locality"];
cell.textLabel.font =[UIFont systemFontOfSize:10.0];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.shadowColor = [UIColor whiteColor];
cell.textLabel.shadowOffset = CGSizeMake(1, 1);
cell.textLabel.highlightedTextColor = [UIColor blackColor];
cell.detailTextLabel.text = [[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"address"];
cell.detailTextLabel.font = [UIFont boldSystemFontOfSize:9.0];
cell.detailTextLabel.textColor = [UIColor grayColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.shadowColor = [UIColor whiteColor];
cell.detailTextLabel.shadowOffset = CGSizeMake(1, 1);
cell.detailTextLabel.highlightedTextColor = [UIColor blackColor];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"rigaLocFooter.png"]];
break;
default:
break;
}
break;
case 2: //review
//header - mappa statica (immagine) - footer (indirizzo)
switch (indexPath.row) {
case 0: //header
if ([[[NSUserDefaults standardUserDefaults] objectForKey:#"language"] isEqualToString:#"it"]) {
cell.textLabel.text = [NSString stringWithFormat:#"Recensioni (%d)",[[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"list_review"] count]];
} else {
cell.textLabel.text = [NSString stringWithFormat:#"Review (%d)",[[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"list_review"] count]];
}
cell.textLabel.font = [UIFont boldSystemFontOfSize:11.0];
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.shadowColor = [UIColor whiteColor];
cell.textLabel.shadowOffset = CGSizeMake(1, 1);
cell.textLabel.highlightedTextColor = [UIColor blackColor];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"rigaLocHeader.png"]];
break;
case 1: //review
cell.textLabel.text = [[[[[SingletonCardPOI sharedCardPOI] dicCard] objectForKey:#"list_review"] objectAtIndex:0] objectForKey:#"review"];
cell.textLabel.font =[UIFont systemFontOfSize:10.0];
cell.textLabel.lineBreakMode = UILineBreakModeTailTruncation;
cell.textLabel.numberOfLines = 3;
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.textColor = [UIColor blackColor];
cell.textLabel.shadowColor = [UIColor whiteColor];
cell.textLabel.shadowOffset = CGSizeMake(1, 1);
cell.textLabel.highlightedTextColor = [UIColor blackColor];
cell.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"rigaRevBody.png"]];
break;
default:
break;
}
break;
default:
break;
}
return cell;
}
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {
UITableViewCell *cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
return cell;
}
The EXC_BAD_ACCESS isn't caused by the progression of one view to the next. Rather, it will be properties of those views, or the creation and release - or not - of the view objects themselves that are to blame.
Your first step is to run the Analyzer. Then, if you've fixed all that and theres still a problem, start running the Leaks tool in Instruments.
For more details on resolving EXC_BAD_ACCESS issues, along with the excellent link on what causes these errors and step by step instructions for how to fix, have a look at answers to these questions:
finding reason for EXC_BAD_ACCESS - in Xcode4
Random EXC_BAD_ACCESS in a place that it cannot happen
In your case, I'd specifically look at how you are creating secondView, and what you do with firstView when you return to secondView.
I just spent a week tracking down a EXC_BAD_ACCESS problem in a large app that worked fine before converting it to ARC. I would get the EXC_BAD_ACCESS on the closing bracket of a "switch" construct. Yet NSZombieEnabled and the various Instrument settings would not detect anything for me.
What fixed it was putting curlies around the case's that made the difference. I did it for each of them, though perhaps it was critical for only some, i.e.
Before:
case ...:
stmt;
stmt;
break;
After:
case ...:{
stmt;
stmt;
}break;
This fixed the problem in two places within a large app for me. I know that I read something somewhere about ARC and switch/case (and maybe someone can add a link to it), but I don't understand the theory behind why this happened and why this fix worked. Perhaps someone could explain. (Later: after reading the following reference at openradar, it all makes sense --- there is something wrong in the "cleanup code" generated between case statements --- a bogus "release" is generated and that soon causes the EXC_BAD_ACCESS.)
I also discovered this, which might be related: http://openradar.appspot.com/11329693
I am a little OCD and this is driving me insane. I have been messing around with these settings for a long time.
I have a UITableView grouped that I have a shadow on the top. When you tap the top cell, it removes. What gives?
I've been stressing over this for the past hour or so. Is there a simple solution for this? Or am I just going insane?
Thanks,
Coulton
EDIT:
viewDidLoad:
formTableView.backgroundColor = [UIColor clearColor];
formTableView.layer.borderColor = [UIColor clearColor].CGColor;
formTableView.separatorColor = [UIColor colorWithRed:(194.0 / 255.0) green:(194.0 / 255.0) blue:(194.0 / 255.0) alpha: 1];
Here is how I display my cells. WARNING: It's a lot of code. There's a bunch of stuff in there you will have to sort through, so sort through it at your own risk! :)
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleNone;
}
// What to do when you click delete.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
return NO;
}
//RootViewController.m
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (section == 0) {
return [formDataOne count];
} else {
return [formDataTwo count];
}
}
//RootViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
for (UIView *subview in [cell.contentView subviews]) {
[subview removeFromSuperview];
}
// Set up the cell...
NSString *cellValue;
if (indexPath.section == 0) {
cellValue = [formDataOne objectAtIndex:indexPath.row];
} else {
cellValue = [formDataTwo objectAtIndex:indexPath.row];
}
if (indexPath.section == 0) {
cell.text = #"";
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (indexPath.row == 0) {
addTitle = [[UITextField alloc] initWithFrame:CGRectMake(13, 13, 280, 20)];
addTitle.borderStyle = UITextBorderStyleNone;
addTitle.textColor = [UIColor blackColor]; //text color
addTitle.font = [UIFont systemFontOfSize:16.0]; //font size
addTitle.placeholder = #"Album Name"; //place holder
addTitle.backgroundColor = [UIColor clearColor]; //background color
addTitle.autocorrectionType = UITextAutocorrectionTypeNo; // no auto correction support
addTitle.keyboardType = UIKeyboardTypeDefault; // type of the keyboard
addTitle.returnKeyType = UIReturnKeyDone; // type of the return key
addTitle.clearButtonMode = UITextFieldViewModeWhileEditing; // has a clear 'x' button to the right
addTitle.delegate = self; // let us be the delegate so we know when the keyboard's "Done" button is pressed
[cell.contentView addSubview:addTitle];
} else if (indexPath.row == 1) {
// Set up loading text and show it
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(13, 13, 280, 20)];
myLabel.text = #"Private Album";
myLabel.textColor = [UIColor blackColor];
myLabel.textAlignment = UITextAlignmentLeft;
myLabel.backgroundColor = [UIColor clearColor];
myLabel.font = [UIFont fontWithName:#"Helvetica" size: 16.0];
myLabel.numberOfLines = 0;
//[myLabel sizeToFit];
privateSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(199, 8, 0, 0)];
[privateSwitch addTarget:self action:#selector(switchToggled:) forControlEvents: UIControlEventTouchUpInside];
[cell.contentView addSubview:privateSwitch];
//[privateSwitch setOn:NO animated:NO];
if ([howToDisplay isEqualToString:#"no"]) {
[privateSwitch setOn:NO animated:NO];
} else {
[privateSwitch setOn:YES animated:NO];
}
[cell.contentView addSubview:myLabel];
} else {
// Set up loading text and show it
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(13, 13, 280, 20)];
myLabel.text = #"Comments";
myLabel.textColor = [UIColor blackColor];
myLabel.textAlignment = UITextAlignmentLeft;
myLabel.backgroundColor = [UIColor clearColor];
myLabel.font = [UIFont fontWithName:#"Helvetica" size: 16.0];
myLabel.numberOfLines = 0;
//[myLabel sizeToFit];
[cell.contentView addSubview:myLabel];
commentsSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(199, 8, 0, 0)];
[cell.contentView addSubview:commentsSwitch];
[commentsSwitch setOn:YES animated:NO];
}
} else {
//cell.text = cellValue;
UILabel *labelOne = [[UILabel alloc] initWithFrame:CGRectMake(48, 12, 130, 20)];
labelOne.text = cellValue;
labelOne.textColor = [UIColor blackColor];
[labelOne setFont:[UIFont boldSystemFontOfSize:16]];
labelOne.textAlignment = UITextAlignmentLeft;
labelOne.backgroundColor = [UIColor clearColor];
//labelOne.font = [UIFont fontWithName:#"Helvetica"];
labelOne.numberOfLines = 0;
[cell.contentView addSubview:labelOne];
if (indexPath.row == 0) {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
} else if (indexPath.row == 1) {
int countFacebook = [dataCeter.connectionFacebookArray count];
if (countFacebook == 0) {
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
} else {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
} else if (indexPath.row == 2) {
//} else if (indexPath.row == 3) {
} else if (indexPath.row == 3) {
int countTumblr = [dataCeter.connectionTumblrArray count];
if (countTumblr == 0) {
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
} else {
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
} else if (indexPath.row == 4) {
} else if (indexPath.row == 5) {
} else {
cell.selectionStyle = UITableViewCellSelectionStyleBlue;
}
}
// Set imageView with correct thumbnail
UIImage *theImage;
if ([cellValue isEqualToString:#"Facebook"]) {
theImage = [UIImage imageNamed:#"icon_small_facebook.png"];
int countFacebook = [dataCeter.connectionFacebookArray count];
NSLog(#"facebook? %d // %#", countFacebook, dataCeter.connectionFacebookArray);
if (countFacebook != 0) {
facebookSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(199, 8, 0, 0)];
[cell.contentView addSubview:facebookSwitch];
[facebookSwitch setOn:YES animated:NO];
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
} else if ([cellValue isEqualToString:#"Twitter"]) {
theImage = [UIImage imageNamed:#"icon_small_twitter.png"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if ([cellValue isEqualToString:#"Flickr"]) {
theImage = [UIImage imageNamed:#"icon_small_flickr.png"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else if ([cellValue isEqualToString:#"Tumblr"]) {
theImage = [UIImage imageNamed:#"icon_small_tumblr.png"];
int countTumblr = [dataCeter.connectionTumblrArray count];
if (countTumblr != 0) {
tumblrSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(199, 8, 0, 0)];
[cell.contentView addSubview:tumblrSwitch];
[tumblrSwitch setOn:YES animated:NO];
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
} else if ([cellValue isEqualToString:#"Email"]) {
theImage = [UIImage imageNamed:#"icon_small_email.png"];
int countEmail = [dataCeter.connectionEmailArray count];
} else if ([cellValue isEqualToString:#"MMS"]) {
theImage = [UIImage imageNamed:#"icon_small_mms.png"];
int countMMS = [dataCeter.connectionSMSArray count];
} else if ([cellValue isEqualToString:#"Photostream"]) {
theImage = [UIImage imageNamed:#"icon_small_photostream.png"];
cell.accessoryType = UITableViewCellAccessoryNone;
photostreamSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(199, 8, 0, 0)];
[cell.contentView addSubview:photostreamSwitch];
[photostreamSwitch setOn:YES animated:NO];
} else {
theImage = nil;
cell.accessoryType = UITableViewCellAccessoryNone;
}
cell.imageView.image = theImage;
return cell;
}
Set your table view's separator style to UITableViewCellSeparatorStyleSingleLine. It's currently being set to UITableViewCellSeparatorStyleSingleLineEtched, which gives the effect of a doubled top border on the iPhone (it looks more detailed on iOS 5, and on iOS 3.2 and 4 on the iPad).
You're not insane, it looks like there is an extra pixel in there.
Try taking out "Sharing" and see if it still happens. Curious to see if the shadow is on "Sharing" or the table itself.
If that's the case, then you know your header view has a problem, not the table view.