Reputation: 4703
I am having trouble referencing a UITextField. Right now I am using an UIAlertView to verify the reference. In this App I have several views that are to be extremely similar and have built a HelperClass(I am not supposed to subclass a UIViewController?) The View Controllers I have are passing the delegate messages along to the TableItemsHelperClass. In that TableItemsHelperClass I am dynamically adding the cells to the table. Now I am running into an issue referencing those cells, my end goal is to handle releasing the first responder(the keyboard) but would be happy with grabbing the Textfields content to verify the reference.
update I have re-factored from using a HelperClass to subclassing UIViewController. Some of the Variable names have changed. Both of these methods are found in the parent class. I now have the case that if
tableView:didSelectRowAtIndexPath:
callstableView:cellForRowAtIndexPath:
thenis nil
is logged. Why am I not getting the cell back?
//tableView cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = [NSString stringWithFormat:@"Cell %d", indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell != nil) {
NSLog(@"is not nil");
return cell;
}
NSLog(@"is nil");
CGRect CellFrame = CGRectMake(0, 0, 300, 65);
CGRect LabelViewFrame = CGRectMake(5, 5, 290, 25);
CGRect TextViewFrame = CGRectMake(5, 35, 290, 25);
cell = [[[UITableViewCell alloc] initWithFrame:CellFrame
reuseIdentifier:CellIdentifier] autorelease];
textFieldView = [[UITextField alloc] initWithFrame:TextViewFrame];
labelView = [[UILabel alloc] initWithFrame:LabelViewFrame];
textFieldView.backgroundColor = [UIColor greenColor];
labelView.backgroundColor = [UIColor redColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if (@"int" == [self.taxPayerTypes objectAtIndex:indexPath.row]) {
textFieldView.keyboardType = UIKeyboardTypeDecimalPad;
}
if (0 == indexPath.section) {
[labelView setText:[self.taxPayerList objectAtIndex:indexPath.row]];
} else {
[labelView setText:[self.spouseList objectAtIndex:indexPath.row]];
}
[cell.contentView addSubview:textFieldView];
[cell.contentView addSubview:labelView];
return cell;
}
//tableView didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
for(UIView *i in [[[self tableView:tableView cellForRowAtIndexPath:indexPath] contentView] subviews]) {
if ([i isKindOfClass:[UITextField class]]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSStringFromClass([i class])
message:[i text]//[(UITextField*)i text]
delegate:self
cancelButtonTitle:@"a"
otherButtonTitles:@"b", nil];
[alert show];
[alert release];
}
}
}
Original
//in the UIViewController/////////////////////////////////////////////////////////////////////////////////
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
return [TableItemsHelper tableView:tableView cellForRowAtIndexPath:indexPath];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
for(UIView *i in [[[TableItemsHelper tableView:tableView cellForRowAtIndexPath:indexPath] contentView] subviews]) {
if ([i isKindOfClass:[UITextField class]]) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSStringFromClass([i class])
message:[i text]
delegate:self
cancelButtonTitle:@"button 1"
otherButtonTitles: @"button", nil];
[alert show];
[alert release];
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
//In the TableItemsHelperClass//////////////////////////////////////////////////////////////////////////
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
CGRect CellFrame = CGRectMake(0, 0, 300, 65);
CGRect TextViewFrame = CGRectMake(5, 35, 290, 25);
// …
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame
reuseIdentifier:CellIdentifier] autorelease];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier] autorelease];
}
UITextFieldView = [[UITextField alloc] initWithFrame:TextViewFrame];
[cell.contentView addSubview:UITextFieldView];
return cell;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
Upvotes: 0
Views: 529
Reputation: 9132
In cellForRowAtIndexPath
// use local variable, not instance variable
UITextField *textField = [[UITextField alloc] initWithFrame:TextViewFrame];
// tag it for later access
textField.tag = 1;
[cell.contentView addSubview:textField];
[textField release];
In didSelectRowAtIndexPath
// NOT [TableItemsHelper tableView:cellForRowAtIndexPath:]
// that would give you a new cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UITextField *textField = [cell viewWithTag:1];
// do what you want with textField
"I am not supposed to subclass a UIViewController?"
No that's not true. In fact it looks like your code is subclassing UIViewController. But maybe you mean you think you are not supposed to subclass your subclass of UIViewController, like:
@interface MyViewController : UIViewController
@interface MyViewControllerFirstVariant : MyViewController
@interface MyViewControllerSecondVariant : MyViewController
I don't know, I think you can do that if you want. But I think the design pattern of using a helper class is cleaner.
Upvotes: 0
Reputation: 5960
I'm not sure why you are under the impression that you aren't supposed to subclass UIViewController. (Virtually all of your view controllers subclass UIViewController, and if you have several view controllers that are nearly identical, you may benefit by subclassing them from another one that you create.) But that doesn't seem relevant to your question.
What you appear to be doing is easier to do if you subclass UITableViewCell to create your own custom cell. Then your "UITextFieldView" can be a property of the subclassed cell, making it directly accessible, instead of using your test loop to find the subview with that class type.
(By the way, your variable naming seems to defy common conventions, potentially making the code a little bit difficult to read. You may want to use a variable name like "textFieldView" rather than "UITextFieldView". The former looks like a conventional variable name, and the latter looks like a conventional class name.)
Your "helper class" can be replaced by the subclass for a UITableViewCell. There are several examples on subclassing UITableViewCell on the net. If you need some references, let me know, and I'll post some links (once I get in front of a computer I can work with :)
I hope this helps, and you don't mind the other editorial comments I made.
Upvotes: 1