1

これはかなり奇妙だと思います。だから私は を持っていて、すべてUIViewの を変更したいと思います。これが私がしたことです:textcolorUILabel

for (UILabel *label in [self subviews]) { // self is the UIView
    label.textColor = someColor;
}

コードを実行すると、次のようなエラーでクラッシュしましたUIImageView: unrecognized selector setTextColor: sent to instance (some instance)

したがってlabel、高速列挙の は実際にはUIImageView. ちなみに、 には が 2 つUIImageViewありUIView *selfます。ただし、高速列挙はのみを与えるべきではありませんか (の代わりUILabelに指定したため)。UILabel *labelUIView *label

次のコードを書いたときに動作するので、これが問題だと思います。

for (UILabel *label in [self subviews]) { // self is the UIView
    if ([label isKindOfClass:[UILabel class]]) {
        label.textColor = someColor;
    }
}

したがって、このコードでは、 が であることを確認してから を設定labelすると、ビュー内のすべての が色を正しく変更します。UILabeltextcolorUILabel

if-statementインスタンスタイプを再確認する必要がある理由を誰か説明できますか?

4

6 に答える 6

5

列挙を「サブビュー内のすべての UILabel のループ」として読んでいますが、実際にはそうではありません.高速列挙はスマートフィルタリングを行わず、単なるショートカットです。「UILabels である私のサブビュー内のすべてのオブジェクトのループ」として読む必要があります。また、すべてのサブビューが実際には UILabel であるとは限らないため、それらすべてを 1 つとして処理しようとすると問題が発生します。

その配列内のすべてのオブジェクトはただしになるUIViewため、よりわかりやすい構文は次のようになります。

for (UIView * view in self.subviews) {
    if ([view isKindOfClass:[UILabel class]]) {
        UILabel * label = (UILabel *)view;
        // do something with label...
    }
}
于 2013-08-04T14:32:31.000 に答える
5

あなたの2つのループは非常に異なります。1 つ目はすべてのサブビューがラベルであると想定し、2 つ目は各サブビューをチェックしてラベルであることを確認します。最初のものもチェックする必要があります。

高速列挙は基本的に構文糖衣であり、通常のforループです。列挙するために指定したリストを魔法のようにフィルター処理したり操作したりしません。

于 2013-08-04T14:24:52.733 に答える
2

最初のループでは、メイン ビューのすべてのサブビューを反復していますが、2 番目の for ループでは、すべてのオブジェクトを反復していますが、UILabel 型の要素のみを変更しています。

メイン ビューには、UIImageView UILabel などのすべてのタイプのビューを含めることができます。データ型として UIlabel を列挙しても、実際にはデータ型が変更されず、そのタイプの要素のみを列挙することはありません。

于 2013-08-04T14:27:22.457 に答える
0

Objective C では、型キャストはありません。高速列挙を使用してその変数を UILabel に割り当てるだけでは、それを UILabel に型キャストしません。それがクラッシュの理由です。RespondsToSelector を使用するか、isKindOfClass を使用してコードを期待どおりに動作させることができます。

于 2013-08-05T05:06:12.480 に答える
0

[self subviews] は、UIViews への (id) ポインターを含む NSArray を返します。これらは、UILabels を含む任意のタイプのビューである可能性があります。そのため、特定のサブビューが setTextColor をサポートしていない場合、認識できないセレクタ メッセージが表示されます。したがって、 isKindOfClass テストが必要です。または、 RespondsToSelector テストを使用してより一般的にすることもできます。

于 2013-08-04T14:34:48.013 に答える
0

よりエレガント: ラベルにタグを付けます。

#define kLabelOffset 100;

for (int i=kLabelOffset +1; i < totalLabels; i+) {
   UILabel *label = (UILabel*) [self viewWithTag:i];
   label.textColor = someColor;
}
于 2013-08-04T14:32:19.767 に答える