I have a UITextField that I am adding to a UITableViewCell
to use as a search field for a long list of accounts. I have added it as follows:
- (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] autorelease];
}
if ((indexPath.section < accountsection) && (hasSearch) && (indexPath.row == 0))
{
// Search
if (!searchField)
{
searchField = [[UITextField alloc] initWithFrame:CGRectMake(20, 10, cell.frame.size.width - 40, 25)];
[searchField setEnabled:YES];
searchField.placeholder = NSLocalizedString(@"Search", @"search");
searchField.keyboardType = UIKeyboardTypeDefault;
searchField.returnKeyType = UIReturnKeySearch;
searchField.autocorrectionType = UITextAutocorrectionTypeNo;
searchField.clearButtonMode = UITextFieldViewModeAlways;
searchField.delegate = self;
[cell addSubview:searchField];
[searchField release];
}
// Clean up an account label if needed
cell.accessoryType = UITableViewCellAccessoryNone;
cell.textLabel.text = @"";
cell.detailTextLabel.text = @"";
// Show the search field if it was hidden by a text label
searchField.hidden = NO;
[cell bringSubviewToFront:searchField];
}
}
To detect edits to the text field, I have set up the UITextFieldDelegate
in the header and trap the following delegate calls:
@interface AccountViewController : UITableViewController <UITextFieldDelegate> {
BOOL hasSearch;
UITextField *searchField;
...
}
In the implementation, I then handle these delegate methods:
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
NSLog(@"Done editing");
[self filterAccountsBy:textField.text];
[textField resignFirstResponder];
return NO;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSLog(@"Searching for %@", string);
[self filterAccountsBy:string];
return YES;
}
However in the second one, unless I return YES, the text never changes; in the first one, returning YES seems to not affect me. But when I return YES in either, I get a nasty EXC_BAD_ACCESS
.
I must be missing something in my manual adding of this UITextField to my cell but I can't figure out what it is... can anyone assist?
Many thanks.
EDIT: As suggested below, I commented out the filterAccounts call and my app now no longer crashes. Here is the full code for this method:
- (void)filterAccountsBy:(NSString *)filterstring
{
[accounts removeAllObjects];
if (([filterstring length] == 0) && (!isChooser) && (![vpmsConn isDomainLogon])) {
[accounts addObject:[[vpmsConn accounts] objectAtIndex:0]];
}
if ([filterstring length] == 0) {
[accounts addObjectsFromArray:[cache accounts]];
} else {
for (AccountItem *ac in [cache accounts])
{
BOOL found = NO;
// Name search
if ([[ac.clientName uppercaseString] rangeOfString:[filterstring uppercaseString]].location != NSN开发者_如何学PythonotFound) {
found = YES;
}
//more similar searches
if (found) {
[accounts addObject:ac];
}
}
}
[self.tableView reloadData];
}
I am a bit confused, though. When I filter this list using the textFieldShouldReturn and then return NO, it filters properly and does not crash. Something about returning YES from either one of these methods causes the crash after I have filtered. If I have not filtered at all, returning YES is no problem.
Let me know if there is any other code that I should post.
I have resolved the issue but I cannot (due to NDA) post the answer here yet. Those interested, and in the paid iOS developer program, should go to the NDA developer forums and search for UITextField EXC_BAD_ACCESS and you will find the answer...
in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
where is
return cell;
?
I think your UITextField
searchfield
is begin deallocated. If you use self.searchField to set your searchfield
(assuming it's a retained property), that will solve it.
I'm not sure what the rest of your .h looks like. You could do:
@property (nonatomic, retain) UITextField *searchField;
Then in the .m:
@synthesize searchField;
That's what I mean by making search field a retained property. This way your class will keep the search field around.
In - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPathreturn cell;
Donot release serachfield in the event;
Release in dealloc
add @property (nonatomic, retain) UITextField *searchField;
精彩评论