【发布时间】:2013-08-07 16:42:06
【问题描述】:
我正在构建一个视图控制器,我在其中以编程方式将一堆UITextFields 添加到我的视图中。我想用我从 CoreData 加载的一些文本预先填充文本字段,但如果他们愿意,允许用户进入并更改该文本。然后我需要返回并将新文本再次保存回 CoreData,并使用新值执行计算。保存和加载本身不是问题,但我正在寻找一种跟踪用户更改内容的好方法。
过去,我使用UITextField 的.tag 属性和textFieldDidEndEditing: 委托方法来完成此操作。问题是我将在这个视图中有几十个文本字段 - 足以让我不记得 .tag 属于我的模型中的哪个变量。必须回去查看我在创建它时分配的标签会很痛苦,而且整个事情感觉真的很容易出错。此外,我将在多个不同的循环中创建文本字段,因此在创建时为每个文本字段获取一个唯一的标签将很困难(也许不可能?)。
我正在寻找的是一种在我创建 UITextField 时将其“绑定”到模型中的变量的方法,并且从那时起,每当用户更新该文本字段时,我就知道我在模型中指定的值将立即更新以用于将来的计算,并在用户离开屏幕时保存回 CoreData。有没有办法做到这一点?
编辑 1:要注意的另一件事是我的模型本身有点复杂。我有几个不同的自定义NSObject 子类,它们都保存着我的不同数据。一些对象的属性本身就是其他自定义对象。我也有字典,其中的值将是一些自定义对象的实例。
例如,我可能有这些对象:
-
MySmallObject1,具有属性name、size和value(全部为NSStrings) -
MySmallObject2,具有属性date和cost(一个NSDate和一个NSNumber) -
MyBigObject,具有属性box1和box2(分别是MySmallObject1和MySmallObject2实例) -
theDict,这是一个NSDictionary实例,其值为MyBigObjects
所以当我构建我的文本字段时,我实际上可能会沿着一棵看起来像这样的树:
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:在尝试在 cmets 中实施 @Till 的建议时,我开始阅读 tutorial on pointers in 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 世界中的工作方式有点模糊,我认为有些东西我还没有完全理解。
【问题讨论】:
-
添加一个抽象层 - 使用字典将所有内容映射在一起怎么样?
-
@Till:我用我的模型的更多细节编辑了我的 OP。我认为在这种情况下字典不起作用,因为我无法将整个树存储为
key,对吗? -
我只能看到两种基本方法:1. 使用标签,2. 在数据模型中使用指向视图的实例指针。 2. 在大多数情况下肯定是丑陋而纯粹的错误。因此,让我们再仔细检查一下 1... 该标签可能是您的模型的生成值。假设 MySmallObject1 在被询问时呈现一个唯一值(我们称之为 Object-ID)。现在构建一个哈希映射(又名字典),将 ID 链接回控制器中的对象 - 这有意义吗?
-
@Till:嗯,不是真的。您能否详细说明您的建议?如何让我的对象“在被询问时呈现独特的价值”?你的意思是在运行时,当我
init我的一个对象的一个实例时? -
这叫绑定,目前iOS不支持。
标签: ios objective-c model-view-controller uitextfield