4

(今のところ)ビューコントローラのインスタンス化でサブビューのサイズを取得したいだけです。

[これは、前の質問で見つけた単純なケースへの縮小です。ストーリーボードのシーンのサブビューが期待どおりに動作しない理由を理解しようとしています。つまり、XIBのように、実際に画面に描画される前にサブビューのサイズを取得したいだけです]

問題を新しいクリーンなプロジェクトに凝縮するために、私はこれを行います。

  • [ストーリーボードを使用する]をオンにして、新しいシングルビュープロジェクトを作成します
  • 単一のUIViewをデフォルトの既存のものに追加しますMainStoryboard_iPad.storyboard(そして、背景を緑色に変更して見やすくします-寸法をいくらか縮小する以外に、これは、シーンにドラッグするデフォルトのUIViewから行う唯一の変更です)
  • オプション-ナビゲーターでファイルをクリックしViewController.hて、ストーリーボードフレームの下の独自のフレームに表示し、@interfaceディレクティブの下に中括弧のペアを挿入します
  • ストーリーボードのUIViewからcontrolキーを押しながらクリックしてドラッグしViewController.h、アウトレットに名前を付けるように指示しますfirstViewFirstSubView

だから私たちは今のために持っていViewController.hます:

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
{
    IBOutlet UIView *firstViewFirstSubView;
}
@end

次に、このメソッドをViewController.mに追加します。

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    NSLog(@"View Controller will appear. firstViewFirstSubView: %@ ", firstViewFirstSubView);
    NSLog(@"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width,
      firstViewFirstSubView.frame.size.height,
      firstViewFirstSubView.frame.origin.x,
      firstViewFirstSubView.frame.origin.y);
}

この時点で、UIViewサブビューのサイズを取得できると期待しています。ただし、すべて0になります。

2012-11-15 15:21:00.743 StoryboardViewBounds[11132:c07] View Controller will appear. firstViewFirstSubView: <UIView: 0x9379730; frame = (0 0; 0 0); autoresize = TM+BM; layer = <CALayer: 0x9378e40>> 
2012-11-15 15:21:00.744 StoryboardViewBounds[11132:c07] subView's dimmensions: 0.000000 by 0.000000 at 0.000000, 0.000000

私は何が間違っているのですか?これは非常に簡単なように思われるので、ストーリーボードエディタで適切なスイッチをスローするか、ストーリーボードに必要なメソッドを実装するかにかかわらず、単純なものが欠けているに違いないと思います。

4

2 に答える 2

8

これらのディメンションは、の呼び出しlayoutSubviewsが行われたときに計算および設定されます。これは、の後に発生しviewWillAppearます。UIVIewで呼び出された後layoutSubviews、寸法を取得できます。

ビューコントローラにこのメソッドを実装することを検討してくださいviewDidLayoutSubviews。この時点で、サブビューのディメンションを取得できるはずです。この呼び出しはiOS5.0以降で利用可能ですが、ストーリーボードを参照しているので、とにかくそれ以上で作業していると思います。

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    NSLog(@"View Controller did layout subviews. firstViewFirstSubView: %@ ", firstViewFirstSubView);
    NSLog(@"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width,
      firstViewFirstSubView.frame.size.height,
      firstViewFirstSubView.frame.origin.x,
      firstViewFirstSubView.frame.origin.y);
}
于 2012-11-15T22:24:43.983 に答える
8

私が対処せざるを得ない関連する問題があります。これにより、他の誰かがデバッグする日を節約できることを願っています。

私はストーリーボードでそれを見つけています:

  1. segue-pushsがに配置されることはありませ代わりに、直前の別の時間に配置されます)。一方..。 subView-viewDidLayoutSubviews-viewDidAppear
  2. segue-modalにレイアウトされ[navController.storyboard presentViewController:] ますsubViews-viewDidLayoutSubviews

解決策は、を手動でロードするために、のメソッド[self.mySubView layoutSubviews]内に配置することです。viewController-viewDidLayoutSubviewssubViewmySubView

私の場合、視覚的な外観を適切に初期化していないカスタムグラデーションボタンがありました。
ボタンは、カスタムグラデーションボタンを含むを含むに含まscrollViewれていました。 つまり、基本的に...内のビュー内のボタン。 CustomView
scrollView

UINavigationControllerアプリは、他のアプリをロードすることから始まりViewController1ます。
ViewController1押すとストーリーボードsegue-pushを起動するボタンが含まれていますViewController2
これは、ボタンからにコントロールドラッグすることでストーリーボードに配置されましViewController1ViewController2)。

ViewController2scrollview//が含まれていcustomViewますcustomButton
で、独自ViewController2.h/.mファイルを持つカスタムグラデーションボタンである-viewDidLayoutSubviewsを初期化します。グラフィカルに構成するメソッドがあり、ボタンの/プロパティを初期化する必要があります。ただし 、'sでは、フレームは0,0,0,0でした。customButton
GradientButton.minitLayersboundsframe

ViewController2-viewDidLayoutSubviewsself.customButton

いくつかの注意:

  1. はい、[super viewDidLayoutSubviews]冒頭に電話をかけてい-viewDidLayoutSubviewsます。
  2. にレイアウトされている唯一のビュー-viewDidLayoutSubviewsself.viewViewController2ストーリーボードの接続パネルで接続されているのの最初のビューです。私の場合は-self.viewですscrollView)。

解決する:

  1. で、を含むビューViewController2のアウトレットを作成しました。 self.bottomViewself.customButton
  2. で、私はViewController2呼び出す-viewDidLayoutSubviews[self.bottomView layoutSubviews]
    • これにより、customButtonのフレーム/境界が適切に設定されます。
  3. 次に、[self.customButton initLayers]カスタムグラデーションボタンを適切に初期化する呼び出しを行います。

ViewController2-viewDidLayoutSubviews:呼び出しに関するいくつかの注意事項[self.view layoutSubviews]によりbottomView、フレームは初期化されますが、フレームは初期化されませんcustomButton
ビュー階層に関しては、ののに-layoutSubviewsのみ適用され、それらののいずれにも適用されません。 これはストーリーボードの場合にのみ当てはまるようです。 subViewself.viewsubViewsubView
segue-push

ストーリーボードsegue-modalとプログラマティック[navController presentViewController]はどちらも、呼び出されるまでにビュー階層のすべてのレベル(すべての " subViews of subViews")を正しく初期化するようです-viewDidLayoutSubviews

于 2012-11-29T15:03:08.007 に答える