有没有办法自动将UITextField绑定到我的数据模型中的变量?
我正在构建一个视图控制器,我UITextField
编程方式将一堆UITextField
添加到我的视图中。 我想用一些我从CoreData加载的文本预先填充文本字段,但允许用户进入并根据需要更改该文本。 然后我需要返回并将该新文本再次保存回CoreData,并使用新值执行计算。 保存和加载本身不是问题,但我正在寻找一种跟踪用户更改内容的好方法。
在过去,我使用UITextField
的.tag
属性和textFieldDidEndEditing:
delegate方法完成了此操作。 问题是我将在这个视图中有几十个文本域 – 足以让我真的不记得.tag
属于我的模型中的变量。 我必须回过头来查看我在创建它时分配的标签,这将是一种痛苦,而整个事情确实很容易出错。 另外,我将在多个不同的循环中创建文本字段,因此在创建它时为每个文本字段获取唯一标记将很困难(可能不可能?)。
我正在寻找的是在我创建它时将UITextField“绑定”到模型中的变量的方法,并且从那时起就知道,每当用户更新该文本字段时,我在模型中指定的值将立即生效更新以用于将来的计算,并在用户离开屏幕时保存回CoreData。 有没有办法做到这一点?
编辑1:另一件需要注意的事情是我的模型本身有点复杂。 我有几个不同的自定义NSObject
子类,它们都包含我的数据的不同部分。 某些对象具有本身是其他自定义对象的属性。 我也有字典,其中值将是某些自定义对象的实例。
作为一个例子,我可能有这些对象:
-
MySmallObject1
,具有属性name
,size
和value
(所有NSStrings
) -
MySmallObject2
,具有属性date
和cost
(NSDate
和NSNumber
) -
MyBigObject
,它具有属性box1
和box2
(分别是MySmallObject1
和MySmallObject2
实例) -
theDict
,是一个以MyBigObject
为值的NSDictionary
实例
因此,当我构建我的文本字段时,我实际上可能会走下一棵看起来像这样的树:
for (NSString *key in [theDict allKeys]) { UITextField *txt = [[UITextField alloc] initWithFrame:...]; txt.text = [[(MyBigObject *)[theDict objectForKey:key] box1] name]; [self.view addSubview:txt]; }
在这种情况下,我需要知道用户何时更改任何txt
的文本并通过树更新适当的值。
编辑2:在评论中尝试实现@Till的建议时,我开始阅读有关C指针的教程 。 看起来这就是我需要的方式,但是我很难从C世界中获得&
和*
与我在Objective-C世界的最后一次编辑中提到的NSObject子类很好地配合。 为了让@Till的建议起作用,我想我需要以某种方式将我的值的内存位置存储在复杂的对象树中。 所以我上次编辑的代码块将成为:
.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]; }
其中globalCounter
是一个int
,我每次将东西放入tagDict
所以我可以保持它的唯一性。 我想在这种情况下,我可以简单地使用NSArray
,它也可以正常工作,并且可能看起来更清洁一点。 我的计划是在我的testFieldDidEndEditing
使用tagDict
,如:
- (void) textFieldDidEndEditing:(UITextField *)textField { *[tagDict objectForKey:[NSString stringWithFormat:@"%d",textField.tag]] = textField.txt; }
这会导致Assigning to 'id' from incompatible type 'NSString *'
出错。 我不太确定这意味着什么。 有没有办法可以使用“解除引用运算符”来更改我在字典中指向的项目的值?
抛出错误Address expression must be an lvalue or a function designator
。 关于这个指针的东西在Objective C世界中是如何工作的,我仍然有点模糊,我认为有些东西我还没有完全理解。
你可以使用UITextField +块,它可能不那么纠缠。 如果对象具有类似的接口或使用setText:
方法实现一个协议将更容易。
您可以将原始方法与.tag一起使用,但请使用typedef。
typedef enum TFTypes { TFModalType1, TFModalType2, TFModalType3, TFModalType4, TFModalType5, ... } TFType;
我最终做了很多我认为@Till试图提出的建议。 我将一个NSMutableArray *tieArray
和一个int tieCounter
作为NSMutableArray *tieArray
添加到我的视图控制器中。 我的OP中第一个代码块构建UITextFields
的代码现在是:
for (NSString *key in [theDict allKeys]) { UITextField *txt = [[UITextField alloc] initWithFrame:...]; txt.text = [[(MyBigObject *)[theDict objectForKey:key] box1] name]; [self.view addSubview:txt]; txt.tag = self.tieCounter; self.tieCounter ++; [self.tieArray addObject:[[(MyBigObject *)[theDict objectForKey:key] box1] name]]; }
然后在我的textFieldDidEndEditing
- (void) textFieldDidEndEditing:(UITextField *)textField { if ([tieArray objectAtIndex:textField.tag] isKindOfClass:[NSMutableString class]]) { [(NSMutableString *)[tieArray objectAtIndex:textField.tag] setString:textField.text]; } else if (//...More conditions to set other variable types with the syntax as needed) }
请注意,要使其工作, MySmallObject1
和MySmallObject2
所有属性MySmallObject2
需要由isKindOfClass:
check覆盖,实际语法会有所不同,具体取决于该属性的类。
我还没有能够测试这个(并且我的应用程序可能在相当长的一段时间内不会处于可测试状态),但它对我来说是有意义的,并且它不会抛出任何错误或警告。 如果我在实际运行时遇到问题,我会在这里更新。