4

UITextFieldプログラムでビューに一連の s を追加するビュー コントローラーを構築しています。CoreData から読み込んでいるテキストをテキストフィールドに事前に入力したいのですが、ユーザーが必要に応じてそのテキストにアクセスして変更できるようにします。その後、戻ってその新しいテキストを CoreData に再度保存し、新しい値を使用して計算を実行する必要があります。保存と読み込み自体は問題ありませんが、ユーザーが変更した内容を追跡する良い方法を探しています。

以前は、デリゲート メソッドの.tagプロパティを使用してこれを行っていました。問題は、このビューに何十ものテキストフィールドが表示されることです。モデルのどの変数に何が属しているかを本当に思い出せないほどです。作成時に割り当てたタグを調べるために戻って確認するのは面倒で、全体的にエラーが発生しやすいように感じます。さらに、複数の異なるループでテキスト フィールドを作成するので、テキスト フィールドを作成するときに各テキスト フィールドに固有のタグを取得するのは困難です (おそらく不可能でしょうか?)。UITextFieldtextFieldDidEndEditing:.tag

私が探しているのは、モデルの作成時にUITextFieldをモデルの変数に「結び付ける」方法であり、その時点から、ユーザーがそのテキストフィールドを更新するたびに、モデルで指定した値が即座に将来の計算で使用するために更新され、ユーザーが画面を離れると CoreData に保存されます。これを行う方法はありますか?

編集 1: 注意すべきもう 1 つのことは、私のモデル自体がちょっと複雑だということです。いくつかの異なるカスタムNSObjectサブクラスがあり、それらはすべて異なるデータを保持しています。一部のオブジェクトには、それ自体が他のカスタム オブジェクトであるプロパティがあります。値がいくつかのカスタム オブジェクトのインスタンスになる辞書もあります。

例として、次のオブジェクトがあるとします。

  • MySmallObject1、プロパティnamesize、およびvalue(all NSStrings)を持つ
  • MySmallObject2、プロパティdatecost(anNSDateおよび an NSNumber)を持ちます
  • MyBigObject、プロパティbox1およびbox2(それぞれMySmallObject1およびMySmallObject2インスタンス)を持ちます。
  • theDict、値として sNSDictionaryを持つインスタンスです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 のポインターに関するチュートリアルを読み始めました。これは私が行く必要がある方法のようですが、Objective-C の世界からの最後の EDIT で言及した NSObject サブクラスとうまく連携するために、C の世界から&andを取得するのに苦労しています。*@Till の提案を機能させるには、値のメモリ位置をその複雑なオブジェクト ツリーに格納する必要があると思います。したがって、最後の EDIT からの私のコード ブロックは次のようになります。

.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はどこにあるので、それを一意に保つことができます。この場合、単純に を使用するだけで、同じように機能し、おそらく少しきれいに見えると思います。私の計画は、私のように使用することです: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

.tag で元のアプローチを使用できますが、typedef を使用してください。

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

私は@Tillが提案しようとしていたと思うことを大部分行うことになりました。ビューコントローラーにNSMutableArray *tieArrayan とint tieCounterasを追加しました。OP の最初のコード ブロックから@propertiesを構築するためのコードは次のとおりです。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する必要があることに注意してisKindOfClass:ください。実際の構文は、そのプロパティがどのクラスであるかによって少し異なります。

私はまだこれをテストできていません (そして、私のアプリはおそらくかなり長い間テスト可能な状態にならないでしょう) が、それは私にとって理にかなっており、エラーや警告はスローされていません。実際に実行したときに問題が発生した場合は、ここで更新します。

于 2013-08-13T15:37:14.957 に答える
0

UITextField+blocksを使用 すると、もつれが少なくなる可能性があります。また、オブジェクトが同様のインターフェースを持っているか、 のようなメソッドで 1 つのプロトコルを実装すると、はるかに簡単になりますsetText:

于 2013-08-06T15:47:28.997 に答える