Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
I made good progress tonight on TableViews. I did have one problem that I can not seem to solve. I would like to have 3 UITextFields on 1 TableView Cell. In the photo attached you can see the 3 but each one is on a different cell. That was the result earlier, I have changed the code now to try to store the 2 text fields in an array index and then add that to a new array.

Each UITextField is it's own Method so I have 3. I thought I could create a new method that returns an NSArray and that method looked like this.
Code:
-(NSArray *)allThreeRows{
    NSArray *tempArray = [[[NSArray alloc] initWithObjects:[self newFieldItem],[self newFieldMonthly],[self newFieldTotal], nil]autorelease];
    return tempArray;
}
This is one of the UITextFields so you can see the code
Code:
-(UITextField *)newFieldItem{
    UITextField *firstOne = [[[UITextField alloc] initWithFrame:CGRectMake(15, 3, 130, 25.)] autorelease];
    firstOne.borderStyle = UITextBorderStyleRoundedRect;
    firstOne.font = [UIFont boldSystemFontOfSize:17.0];
    firstOne.delegate = self;
    firstOne.returnKeyType = UIReturnKeyDefault;
    return firstOne;
}
In my viewDidLoad I had this code. I know my problem is the line in red since it crashes. I think I am on the right path trying to add the 3 separate textFields to an NSArray and then adding that array as an object to a new array. So I would end up with 1 Array and at each index would be an Array that contained 3 UITextFields. I think I am close to solving it.
Code:
- (void)viewDidLoad
{
   
   [COLOR="Red"]addTextFieldsArray = [[NSMutableArray alloc] initWithObjects:[self allThreeRows], nil];[/COLOR]
    self.navigationController.navigationBarHidden = NO;
    UIBarButtonItem  *newBarItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addTextFieldsToArray)];
    self.navigationItem.rightBarButtonItem = newBarItem;
    [newBarItem release];

    [super viewDidLoad];
    self.view.backgroundColor = [UIColor colorWithRed:1 green:1 blue:0.75 alpha:1]; 
}
 

Attachments

  • 3rows.jpg
    3rows.jpg
    24.5 KB · Views: 162
First, terminology. You say "Each UITextField is it's own Method" but you can't really say that. UITextField is a class. You can have instances of that class, known as objects. Methods are simply the names of messages you send to objects (or classes, in the case of class methods). Based on the code you provided, I would say "I have a method that returns a UITextField".

Second, you haven't shown the code where you add the textFields to the cell.

Third, have you read the Table View Programming Guide, especially the section on Customizing Cells?
 
Where is your tableView:cellForRowAtIndexPath: method? That is generally where you want to perform any cell customization, whether it be adding views to the standard UITableViewCell or creating an instance of a custom cell class.
 
Sorry I thought the problem was adding them to my array. I have 3 Methods that each return a UITextField object. The only difference is the size of the textField.

Here is the code for adding the array to the cell

Code:
- (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] autorelease];
    }
    [cell setBackgroundColor:[UIColor yellowColor]];
    
    // Configure the cell...

    [COLOR="Red"][cell addSubview:[addTextFieldsArray objectAtIndex:indexPath.row]];[/COLOR]
    return cell;
}
 
Each cell is getting one object from your array added to it. Each object in the array is a single UITextField.
 
This Method returns a new Array object that should contain 3 UITextField objects at index 0,1,2. Using an NSLog It prints to screen 3 objects. Which I can see displayed but the next step crashes

Code:
-(NSArray *)allThreeRows{
    NSArray *tempArray = [[[NSArray alloc] initWithObjects:[self newFieldItem],[self newFieldMonthly],[self newFieldTotal], nil]autorelease];
    NSLog(@"%@",tempArray);    
    return tempArray;
}

So now in my view did load I add the array object, which contains the 3 textFields to index 0 of the new addTextFieldsArray
Code:
addTextFieldsArray = [[NSMutableArray alloc] initWithObjects:[self allThreeRows], nil];

Then the cell in the table receives the object at index.row which contain the 3 textFields
Code:
[cell addSubview:[addTextFieldsArray objectAtIndex:indexPath.row]];

But this is what I get. It looks like it is being sent to something that does not exist.
Code:
2011-09-28 13:34:09.992 MoneyList[1237:207] (
    "<UITextField: 0xb108850; frame = (15 3; 130 25); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0xb108960>>",
    "<UITextField: 0xb107ab0; frame = (165 3; 50 25); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0xb107bc0>>",
    "<UITextField: 0xb103260; frame = (235 3; 70 25); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0xb1033f0>>"
)
2011-09-28 13:34:09.995 MoneyList[1237:207] -[__NSArrayI superview]: unrecognized selector sent to instance 0xb109a70
2011-09-28 13:34:09.996 MoneyList[1237:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI superview]: unrecognized selector sent to instance 0xb109a70'
*** Call stack at first throw:
(
	0   CoreFoundation                      0x00dc35a9 __exceptionPreprocess + 185
	1   libobjc.A.dylib                     0x00f17313 objc_exception_throw + 44
	2   CoreFoundation                      0x00dc50bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
	3   CoreFoundation                      0x00d34966 ___forwarding___ + 966
	4   CoreFoundation                      0x00d34522 _CF_forwarding_prep_0 + 50
	5   UIKit                               0x00046365 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 77
	6   UIKit                               0x00044aa3 -[UIView(Hierarchy) addSubview:] + 57
	7   MoneyList                           0x00003124 -[personalTableViewController tableView:cellForRowAtIndexPath:] + 372
	8   UIKit                               0x0008ab98 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634
	9   UIKit                               0x000804cc -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
	10  UIKit                               0x000958cc -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
	11  UIKit                               0x0008d90c -[UITableView layoutSubviews] + 242
	12  QuartzCore                          0x016ada5a -[CALayer layoutSublayers] + 181
	13  QuartzCore                          0x016afddc CALayerLayoutIfNeeded + 220
	14  QuartzCore                          0x016550b4 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
	15  QuartzCore                          0x01656294 _ZN2CA11Transaction6commitEv + 292
	16  QuartzCore                          0x0165646d _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
	17  CoreFoundation                      0x00da489b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
	18  CoreFoundation                      0x00d396e7 __CFRunLoopDoObservers + 295
	19  CoreFoundation                      0x00d021d7 __CFRunLoopRun + 1575
	20  CoreFoundation                      0x00d01840 CFRunLoopRunSpecific + 208
	21  CoreFoundation                      0x00d01761 CFRunLoopRunInMode + 97
	22  GraphicsServices                    0x00ffb1c4 GSEventRunModal + 217
	23  GraphicsServices                    0x00ffb289 GSEventRun + 115
	24  UIKit                               0x00023c93 UIApplicationMain + 1160
	25  MoneyList                           0x00001f89 main + 121
	26  MoneyList                           0x00001f05 start + 53
)
terminate called after throwing an instance of 'NSException'
 
Oh ok, I was wrong about the contents of the array that you are using.

Here's the question to you: what type of argument does addSubview expect, and what are you giving it?
 
I would think the answer is in the question subView would be a view, or a UIView. I know that in my Methods that return a UITextField I create a CGRectMake
Code:
UITextField *firstOne = [[[UITextField alloc] initWithFrame:CGRectMake(15, 3, 130, 25.)] autorelease];
This should add a frame for the subView? But now those are all in my Array. So I am trying to pass an array object as the subView and not the UITextFields contained within the array.

I am at the edge of grasping this. It's like surfing and trying to catch the wave.
 
So now in my view did load I add the array object, which contains the 3 textFields to index 0 of the new addTextFieldsArray
Code:
addTextFieldsArray = [[NSMutableArray alloc] initWithObjects:[self allThreeRows], nil];

Then the cell in the table receives the object at index.row which contain the 3 textFields
Code:
[cell addSubview:[addTextFieldsArray objectAtIndex:indexPath.row]];

You need to break each of these down and figure out what type of object is being messaged.

What type does [self allThreeRows] return?

What type is being added to the new NSMutableArray by initWithObjects:[self allThreeRows], nil ? It's whatever type [self allThreeRows] returns. Note that NSArray's initWithObjects: method is different from initWithArray:. I strongly recommend that you carefully read the reference doc for both methods.

You seem to be copying things around a lot. Why? I get the sense that it's because you're not sure which things are containers (NSArray objects) and which things are the actual text-field objects of interest.

I suggest you draw a diagram (boxes), name each box with its variable name (e.g. addTextFieldsArray, the array returned by allThreeRows, etc.), then carefully figure out which things contain which other things. You need a clear mental picture of this, and you're not even close yet. In fact, you seem to be getting farther away at each iteration.


When you're unsure of what is or isn't a container (an object that can hold other objects), you get crazy things like telling an inanimate dog kennel to roll over, rather than telling the dog inside the kennel to roll over.

Specifically:
Code:
2011-09-28 13:34:09.995 MoneyList[1237:207] -[__NSArrayI superview]: unrecognized selector sent to instance 0xb109a70
This is telling an NSArray object to perform its superview method. Sadly, NSArray's don't have superview methods, so it can't respond.

Why would an NSArray object be told to perform its superview method? Perhaps because you've told a UIView object to addSubview: and the added subview is actually an NSArray.

Code:
	5   UIKit                               0x00046365 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 77
	6   UIKit                               0x00044aa3 -[[COLOR="Red"]UIView(Hierarchy) addSubview[/COLOR]:] + 57
	7   MoneyList                           0x00003124 -[[COLOR="Blue"]personalTableViewController tableView:cellForRowAtIndexPath:][/COLOR] + 372
And I see you're still naming classes with initial lower-case letters (personalTableViewController).


If only there were a class that could hold UIView objects, that was also a UIView object itself. And where you could ask it to return its subviews.

Oh, wait, how about a UIView object, which has a subviews property that returns an NSArray.

So if you put your text fields into a UIView object, and added that to the cell, then you are working with the entire set of 3 text-fields at once. The container UIView is acting as both a container object for subviews, and a single view object itself.
 
Thanks Chown33 for the detailed response and especially the the information on the UIView Object.

What type does [self allThreeRows] return?
It returned an NSArray and at each index of 0,1,2 was a UITextField.

I am aware of the initWithObjects and initWithArray. I will read over both of them again. I was unaware of the UIView returning an array of UIViews. I am learning from Doc's, Youtube tutorials and books. But I am only able to use what I have learned so far to solve problems and the Objective C is huge. There are so many different tutorials on creating a UITableView and then features that are depreciated.

I am not sure what you mean by copying? If you are referring to the [self allThreeRows] my goal was to combined them into 1 NSArray Object that gets returned. Now that I see that UIView object can return an array (thanks for that tid bit) I will read up on it tonight.

As far as naming classes I saw that mistake with the lower case. I am unsure of the best way to fix that? If I rename them in in my bin they won't match the files. I tried to use the refactor / rename but it is grayed out. By mistake the other night i deleted a view in an XIB and I was unable to undo it.

I'm learning.... and thankful for your support as I progress.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.