I'm building up a view controller where I'm adding a bunch of UITextField
s to my view programmatically. I want to pre-populate the textfields with some text that I'm loading from CoreData, but allow the user to go in and change that text if they want. I then need to go back and save that new text back to CoreData again, as well as perform calculations using the new value. The saving and loading itself isn't a problem, but I'm looking for a good way to track what the user has changed.
In the past, I've done this with the .tag
property of the UITextField
and the textFieldDidEndEditing:
delegate method. The problem is I'm going to have dozens of textfields in this view - enough so that I can't really remember what .tag
belongs to what variable in my model. Having to go back to look up what tag I assigned when I created it is going to be a pain, and the whole thing feels really error prone. Additionally, I'm going to be creating the textfields in multiple different loops, so getting a unique tag for each textfield when I create it will be difficult (maybe impossible?).
What I'm looking for is a way to "tie" the UITextField to a variable in my model when I create it and just know from that point on, whenever the user updates that textfield, the value I specify in my model will be instantly updated to be used in future calculations, and saving back to CoreData when the user leaves the screen. Is there a way to do this?
EDIT 1: Another thing to note is that my model itself is kinda complex. I have several different custom NSObject
subclasses that are all holding different pieces of my data. Some of the objects have properties that are themselves other custom objects. I also have dictionaries where the values will be instances of some of the custom objects.
As an example, I might have these objects:
MySmallObject1
, which has propertiesname
,size
, andvalue
(allNSStrings
)MySmallObject2
, which has propertiesdate
andcost
(anNSDate
and anNSNumber
)MyBigObject
, which has propertiesbox1
andbox2
(which areMySmallObject1
andMySmallObject2
instances, respectively)theDict
, which is anNSDictionary
instance that hasMyBigObject
s as values
So when I am building my textfields, I might actually be going down a tree that would look something like:
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 update the appropriate value through the tree.
EDIT 2: While trying to implement @Till's suggestion in the comments, I started reading a tutorial on pointers in C. It seems like this is the way I need to go, but I'm struggling to get the &
and *
from the C world to play nicely with the NSObject subclasses I mention in my last EDIT from the Objective-C world. To get @Till's suggestion to work, I think I need to somehow store the memory location of my value up that complicated object tree. So my code block from the last EDIT would become:
.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
that I'm incrementing every time I put something into tagDict
so I can keep it unique. I guess in this case I could just simply be using an NSArray
and it would work just as well, and probably look 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 throws an error for Assigning to 'id' from incompatible type 'NSString *'
. I'm not really sure what that means. Is there a way I can use a "dereferencing operator" to change the value of the item I am pointing to in my dictionary?
throws an error Address expression must be an lvalue or a function designator
. I'm still a little fuzzy on how this pointer stuff would work in the Objective C world, and I think there's something I'm not fully understanding.