0

UILabelsストーリーボードのそれぞれに対して、アプリケーションでプログラムで 2 つ生成しようとしていますUIImageView。ただし、UIImageView フレーム origin.x,origin.y とは対照的に、メイン ビューの座標 (0.0) にある 2 つの UILabels フォームを最初にロードすると、コードは実行され、正しく動作します。なぜこれが起こっているのか理解できません。

その後、別のタブをクリックしてページに戻ると、ラベルが正しい場所に生成されます。

どうしてこれなの?最初に正しい場所にラベルを生成するにはどうすればよいですか?

-(void) viewWillAppear:(BOOL)animated
{
    //removed unneccessary code above...
    int i = 0;
    for (UIImageView *plantScreen in self.view.subviews)
    {
        if ([plantScreen isMemberOfClass:[Plant class]])
        {
            @try
            {
                //the label which will hold the name
                UILabel *plantName = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height), 160, 30.0)];
                plantName.numberOfLines = 1;
                plantName.minimumScaleFactor = .5;
                plantName.adjustsFontSizeToFitWidth = YES;
                [plantName setTextAlignment:NSTextAlignmentCenter];
                [plantName setBackgroundColor:[UIColor clearColor]];

                [self.view addSubview:plantName];
                plantName.hidden = false; 
                [self.view bringSubviewToFront:plantName];

                //create the label which will hold the quantity
                UILabel *quantity = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height + 20), 160, 30.0)];

                [quantity setTextAlignment:NSTextAlignmentCenter];
                [quantity setBackgroundColor:[UIColor clearColor]];
                quantity.text = [NSString stringWithFormat:@"%d",plant.quantity];
                [self.view addSubview:quantity];
                quantity.hidden = false;
                [self.view bringSubviewToFront:quantity];

                i++;   

            }
            @catch (NSException *exception)
            {   
                NSLog(@"An exception occured: %@", [exception reason]);
            }
            @finally
            {

            }
        }
    }
}
4

2 に答える 2

0

のフレームは、UIImageView描画されるイメージとそのcontentModeプロパティによって異なります。を設定して、割り当てられたフレームを強制的に保持するかどうかを確認できcontentModeますUIViewContentModeScaleAspectFill

于 2013-04-08T22:52:19.337 に答える
0

まず第一に、あなたは への呼び出しを見逃しています[super viewWillAppear:animated]UIViewControllerスーパークラス (基本クラスを含む) に「魔法をかける」機会を与える必要があります。

自分が何をしているのか本当によくわかっていない限り、親クラスにその魔法を行う機会を与えることを決して忘れないでください。

次に、UI の作成は-loadViewではなく で行う必要がありますviewWillAppear:

まずはこの2点を試してみてください。


大丈夫。どうやって に移動したのか気になり-loadViewます。追加しました[super loadView];か?

実際、考えて-loadViewみると、この場合に移動するのは間違っています。明らかに、ペン先を介していくつかのビューをインスタンス化します。UIViewControllerの実装は-loadView通常、nib ファイルをロードするだけです。それが完了すると、UIViewController-loadView呼び出しが-viewDidLoad.

したがって、すべての UI をプログラムで作成するのではなく、代わりにUIViewControllernib からロードできるようにする場合は、実際にはコードを に移動したいと思うでしょう-viewDidLoad。(新しいUIViewControllerサブクラスを作成するよう Xcode に指示すると、Xcode によって生成されるテンプレートを参照してください。)

次に、フレームが依存するものを考えてみましょう。それはあなたが呼んだいくつかのビュークラスに依存しますPlant

そのように呼ばないでください。ややこしい。と呼んでPlantView、コードを何気なく読んだ人が、クラスが何をすべきかを認識できるようにします。同様に、 やplantViewの代わりに変数を呼び出したい場合があります。は、 を含む変数を意味し、 を意味する以上のものを意味します。同じことが当てはまります。この変数を呼び出します。plantScreenplantNameLabelplantNameplantScreenUIScreenplantNameNSStringUILabelquantityquantityLabel

次に、変数が何に依存しているかを考えてみましょう。変数の起源は、カウンター variable に基づいて変化しませxん。おそらく、あなたは次のように書くつもりでした:yi

UILabel *plantName = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height * i), 160, 30.0)];

そして後で:

UILabel *quantity = [[UILabel alloc] initWithFrame:CGRectMake((plantScreen.frame.origin.x), (plantScreen.frame.origin.y+ plantScreen.frame.size.height*i + 20), 160, 30.0)];

次に、例外と例外処理を回避します。他の形式のチェックによって例外が発生しないことを確認します。Appleは、アプリケーションの作成中に例外を修正し、実行時に例外を処理しないことを強くお勧めします。

重要:範囲外のコレクション アクセス、不変オブジェクトの変更の試行、無効なメッセージの送信、ウィンドウ サーバーへの接続の切断など、プログラミングまたは予期しないランタイム エラーのために、例外の使用を予約する必要があります。通常、実行時ではなくアプリケーションの作成時に例外を除いて、この種のエラーに対処します。

次に、ちょっとした文体上の注意点 (あまり重要ではありません): プロパティを介して呼び出しているセッターと、直接呼び出しているセッターを混在させています。何も悪いことはありませんが (最終的にはまったく同じことをします)、スタイル的にはあまり良くありません。

次に、ARC (自動参照カウント) を使用している場合を除き、サブビューとして追加されたらビューを解放することを忘れないでください。

次に、plantScreen(以下で名前を付けました) は、ループ内で宣言されたときにplantView型をPlant(以下で名前を付けました) に設定できます。PlantView

最後になりますが、非常に重要であり、非常に見落としがちです: のisMemberOfClass:代わりに関数を呼び出しますisKindOfClass:

コードの修正版 (未テスト):

-(void)viewDidLoad
{
    [super viewDidLoad];

    int i = 0;
    for (PlantView *plantView in self.view.subviews)
    {
        if ([plantView isKindOfClass:[PlantView class]])
        {
            //the label which will hold the name
            CGRect plantNameLabelFrame = CGRectMake((plantScreenView.frame.origin.x),
                                                   (plantScreenView.frame.origin.y + plantScreen.frame.size.height*i), 
                                                  160, 
                                                  30.0);
            UILabel *plantNameLabel = [[UILabel alloc] initWithFrame: plantNameLabelFrame];
            plantNameLabel.numberOfLines = 1;
            plantNameLabel.minimumScaleFactor = .5;
            plantNameLabel.adjustsFontSizeToFitWidth = YES;
            plantNameLabel.textAlignment = NSTextAlignmentCenter;
            plantNameLabel.backgroundColor:[UIColor clearColor];

            [self.view addSubview:plantNameLabel];
            [plantNameLabel release];

            //create the label which will hold the quantity
            CGRect quantityLabelFrame = CGRectMake((plantScreenView.frame.origin.x),
                                                      (plantScreenView.frame.origin.y + plantScreen.frame.size.height*i + 20), 
                                                      160, 
                                                      30.0);
            UILabel *quantityLabel = [[UILabel alloc] initWithFrame: quantityLabelFrame];
            quantityLabel.textAlignment = NSTextAlignmentCenter;
            quantityLabel.backgroundColor = [UIColor clearColor];
            quantityLabel.text = [NSString stringWithFormat:@"%d", plant.quantity]; // NB: what's "plant"?
            [self.view addSubview:quantityLabel];

            i++;
       }
    }
}

.hidden = falseまた、 (これは実際に読む必要があります.hidden = NO。これは Objective-C であり、C++ ではありません) とbringSubviewToFront:(既に前面にあり、によって追加されたばかりです)も削除しましたaddSubview:

于 2013-04-08T22:41:24.920 に答える