4

UITextField我正在构建一个视图控制器,我在其中以编程方式将一堆s 添加到我的视图中。我想用我从 CoreData 加载的一些文本预先填充文本字段,但如果他们愿意,允许用户进入并更改该文本。然后我需要返回并将新文本再次保存回 CoreData,并使用新值执行计算。保存和加载本身不是问题,但我正在寻找一种跟踪用户更改内容的好方法。

过去,我使用the和委托方法的.tag属性来完成此操作。问题是我将在这个视图中有几十个文本字段 - 足以让我不记得什么属于我的模型中的哪个变量。必须回去查看我在创建它时分配的标签会很痛苦,而且整个事情感觉真的很容易出错。此外,我将在多个不同的循环中创建文本字段,因此在创建时为每个文本字段获取一个唯一的标签将很困难(也许不可能?)。UITextFieldtextFieldDidEndEditing:.tag

我正在寻找的是一种在创建 UITextField 时将其“绑定”到模型中的变量的方法,并且从那时起就知道,每当用户更新该文本字段时,我在模型中指定的值将立即生效更新以用于将来的计算,并在用户离开屏幕时保存回 CoreData。有没有办法做到这一点?

编辑 1:要注意的另一件事是我的模型本身有点复杂。我有几个不同的自定义NSObject子类,它们都保存着不同的数据。一些对象的属性本身就是其他自定义对象。我也有字典,其中的值将是一些自定义对象的实例。

例如,我可能有这些对象:

  • MySmallObject1, 具有属性name, size, 和value(all NSStrings)
  • MySmallObject2, 它具有属性dateand cost(anNSDate和 an NSNumber)
  • MyBigObject,它具有属性box1box2(分别是MySmallObject1MySmallObject2实例)
  • theDict,这是一个以s 为值的NSDictionary实例MyBigObject

因此,当我构建我的文本字段时,我实际上可能会沿着一棵看起来像这样的树走下去:

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 世界的&and*与我在 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增加,这样我就可以保持它的独特性。我想在这种情况下,我可以简单地使用 an并且它也可以正常工作,并且可能看起来更干净一些。我的计划是像我一样使用:inttagDictNSArraytagDicttestFieldDidEndEditing

- (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世界中的工作方式仍然有点模糊,我认为有些东西我还没有完全理解。

4

3 回答 3

0

您可以使用UITextField+blocks 它可能会减少纠缠。如果对象具有类似的接口或使用类似setText:.

于 2013-08-06T15:47:28.997 回答
0

您可以将原始方法与 .tag 一起使用,但使用 typedefs。

typedef enum TFTypes {
    TFModalType1,
    TFModalType2,
    TFModalType3,
    TFModalType4,
    TFModalType5,
    ...
} TFType;
于 2013-08-06T15:56:00.600 回答
0

我最终做了大部分我认为@Till 试图建议的事情。我在视图控制器中添加了一个NSMutableArray *tieArray和一个。我从我的 OP 中的第一个代码块构建的代码现在是:int tieCounter@propertiesUITextFields

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并且实际语法会根据该属性的类而有所不同。MySmallObject2isKindOfClass:

我还不能对此进行测试(而且我的应用程序可能在很长一段时间内都不会处于可测试状态),但这对我来说很有意义,并且它不会引发任何错误或警告。如果我在实际运行它时遇到问题,我会在这里更新。

于 2013-08-13T15:37:14.957 回答