3 UITextFields in a UITableView Cell

Discussion in 'iOS Programming' started by larswik, Sep 28, 2011.

  1. larswik macrumors 68000

    Joined:
    Sep 8, 2006
    #1
    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]; 
    }
    
     

    Attached Files:

  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    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?
     
  3. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #3
    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.
     
  4. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #4
    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;
    }
    
     
  5. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #5
    Each cell is getting one object from your array added to it. Each object in the array is a single UITextField.
     
  6. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #6
    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'
    
     
  7. admanimal macrumors 68040

    Joined:
    Apr 22, 2005
    #7
    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?
     
  8. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #8
    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.
     
  9. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #9
    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.
     
  10. larswik thread starter macrumors 68000

    Joined:
    Sep 8, 2006
    #10
    Thanks Chown33 for the detailed response and especially the the information on the UIView Object.

    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.
     

Share This Page