I create a view controller where I add a bunch of UITextField to my view programmatically. I want to prefill the text fields with the text that I download from CoreData, but allow the user to enter and change this text if he wants. Then I need to go back and save this new text back to CoreData, and also perform calculations using the new value. Saving and loading on their own is not a problem, but I'm looking for a good way to track user changes.
In the past, I did this using the .tag property of the delegate method UITextField and textFieldDidEndEditing: The problem is that in this view I will have many text fields - enough so that I canโt remember that .tag belongs to which variable in my model. To go back to find out which tag I assigned when I created it, it will be a pain, and it all seems really error prone. In addition, I am going to create text fields in several different loops, so getting a unique tag for each text field when creating it will be difficult (perhaps impossible?).
What I'm looking for is a way to bind a UITextField to a variable in my model, when I create it and just know from that point, when the user updates this text box, the value specified in my model will be instantly updated for use in future calculations and save back to CoreData when the user leaves the screen. Is there any way to do this?
EDIT 1: Another thing that should be noted is that my model itself is complex. I have several different custom subclasses of NSObject that contain different parts of my data. Some objects have properties that are themselves other custom objects. I also have dictionaries where the values โโwill be instances of some user objects.
As an example, I can have the following objects:
MySmallObject1 , which has the properties name , size and value (all NSStrings )MySmallObject2 , which has date and cost properties (an NSDate and a NSNumber )MyBigObject , which has box1 and box2 properties (which are instances of MySmallObject1 and MySmallObject2 respectively)theDict , which is an instance of NSDictionary , which has MyBigObject as values
Therefore, when I create my text fields, I could go down the tree, which would look something like this:
for (NSString *key in [theDict allKeys]) { UITextField *txt = [[UITextField alloc] initWithFrame:...]; txt.text = [[(MyBigObject *)[theDict objectForKey:key] box1] name]; [self.view addSubview:txt]; }
In this case, I need to know when the user changes the text in any of the txt and updates the corresponding value through the tree.
EDIT 2: When trying to implement @ In addition to the comments, I started reading the guide on pointers in C. It seems like this is the way I need to go, but I try my best to get & and * from the C world to play well with the NSObject subclasses that I mention in my last EDIT from the Objective-C world To get @ Think about how to work, I think I need to somehow save the memory cell of my value in this complex tree of objects. So my block of code from the last EDIT would look like this:
.h @property (nonatomic, strong) NSMutableDictionary *tagDict; .m for (NSString *key in [theDict allKeys]) { UITextField *txt = [[UITextField alloc] initWithFrame:...]; txt.text = [[(MyBigObject *)[theDict objectForKey:key] box1] name]; txt.tag = globalCounter; [tagDict addObject:[[(MyBigObject *)[theDict objectForKey:key] box1] name] forKey:[NSString stringWithFormat:@"%d",globalCounter]]; globalCounter ++; [self.view addSubview:txt]; }
Where globalCounter is an int , which I increment every time I put something in a tagDict , so I can keep it unique. I think in this case I could just use NSArray and it will work just as well, and probably looks a little cleaner. My plan is to use tagDict in my testFieldDidEndEditing like:
- (void) textFieldDidEndEditing:(UITextField *)textField { *[tagDict objectForKey:[NSString stringWithFormat:@"%d",textField.tag]] = textField.txt; }
This causes an error for Assigning to 'id' from incompatible type 'NSString *' . I'm not quite sure what that means. Is there a way that I can use the "dereference operator" to change the value of the element that I point to in my dictionary?
throws an error Address expression must be an lvalue or a function designator . I'm still a little vague in how this pointer material will work in the Objective-C world, and I think there is something I donโt quite understand.