web-dev-qa-db-ja.com

iOS AutoLayout-フレームサイズの幅を取得

IOS 6自動レイアウトを使用して開発しています

ビューのフレーム幅を表示するメッセージを記録したいと思います。

画面にtextViewが表示されます。

しかし、幅と高さをゼロとして取得します、何かが足りませんか?

NSLog(@"textView    = %p", self.textView);
NSLog(@"height      = %f", self.textView.frame.size.height);
NSLog(@"width       = %f", self.textView.frame.size.width);

textView    = 0x882de00
height      = 0.000000
width       = 0.000000
57
user1046037

自動レイアウトには、これを呼び出すまでにビューをレイアウトする時間がありませんでした。 viewDidLoadが呼び出されるまで自動レイアウトは発生していません。ビューがロードされた直後に呼び出され、その後ビューがView Controllerのビュー階層に配置され、最終的に(ビューのlayoutSubviewsメソッド)。

編集:この回答は、質問のシナリオが機能しない理由を指摘しています。 @ dreamzor's answer は、コードを解決するためにコードを配置する場所を示しています。

56
Jesper

実際、上記の答えはまったく正しくありません。私はそれらに従い、何度もゼロを取得しました。

トリックは、フレーム依存コードをviewDidLayoutSubviewsメソッドに配置することです。

ビューがサブビューをレイアウトしたことをView Controllerに通知します。

このメソッドは複数回呼び出され、ViewControllerのライフサイクルの一部ではないことを忘れないでください。そのため、これを使用するときは注意してください。

それが誰かに役立つことを願っています。

追加したかったのは、ランドスケープモードのない私のプログラムでは、自動レイアウトを使用しない方がはるかに簡単だということです...

154
dreamzor

ViewDidLoad()に含める

self.view.setNeedsLayout()
self.view.layoutIfNeeded()

Yourview.frame.size.widthにアクセスする前に

30
diegosantiviago

ソリューション

  • そのコードをviewDidAppearに配置します

理由

  • viewDidLoadは、自動レイアウトが完了する前に発生します。したがって、位置はxibで指定された自動レイアウトによってまだ設定されていません
  • viewDidAppearは、自動レイアウトが完了した後に発生します。
29
user1046037

実際には、viewDidLoad内のコードの前にforceを更新しました。

override func viewDidLoad() {
        super.viewDidLoad()

        println("bounds before \(self.previewContainer.bounds)");
        //on iPhone 6 plus -> prints bounds before (0.0,0.0,320.0,320.0)

        self.view.setNeedsLayout()
        self.view.layoutIfNeeded()

        println("bounds after \(self.previewContainer.bounds)");
        //on iPhone 6 plus -> prints bounds after (0.0,0.0,414.0,414.0)

        //Size dependent code works here
        self.create()
    }

[〜#〜] update [〜#〜]:これはもう機能しないようです

13
Francescu

これは本当に奇妙な機能です。しかし、私は見つけた:

Layoutsubviewsメソッドを使用せずにフレームを取得する場合は、次のメソッドを使用します。

dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"View frame: %@", NSStringFromCGRect(view.frame));
    });

これは本当に奇妙です!!!

10
SamSol

viewDidLoadを除いて、上記の回答は完全に機能しませんでしたが、ビューがアニメーション化されるまでは必要なものが表示されないという副作用があります。

viewDidLayoutSubviewsshouldは、自動レイアウトの完了に依存するコードを実行する正しい場所ですが、他の人が指摘しているように、最近のiOSバージョンでは複数回呼び出され、わかりませんこれが最後の呼び出しです。

そこで、私はこれを小さなハックで解決しました。私の絵コンテでは、mySubviewは含まれるself.viewよりも小さくなければなりません。ただし、viewDidLayoutSubviewsが最初に呼び出されたとき、mySubviewの幅は600のままですが、self.viewは正しく設定されているようです(これはiPhoneプロジェクトです)。したがって、私がしなければならないのは、後続の呼び出しを監視し、相対的な幅をチェックすることだけです。 mySubviewself.viewより小さいと、正しくレイアウトされていると確信できます。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if self.mySubview.bounds.size.width < self.view.bounds.size.width {

        // mySubview's width became less than the view's width, so it is
        // safe to assume it is now laid out correctly...

    }
}

これには、ハードコードされた数字に依存しないという利点があるため、たとえば、すべてのiPhoneフォームファクターで機能します。もちろん、すべてのケースまたはすべてのデバイスで万能薬ではないかもしれませんが、おそらく相対的なサイズの同様のチェックを行うための多くの独創的な方法があります。

いいえ、これを行う必要はありませんが、Appleがより信頼性の高いコールバックを提供するまで、私たちはすべてそれにこだわっています。

7
Echelon

iOS AutoLayout-フレームサイズの幅を取得

 -(void) layoutSubviews{
        [self layoutIfNeeded];
        //right you code to set frame its will work to get frame and set frame.
        CALayer *bottomBorder = [CALayer layer];
        bottomBorder.frame = CGRectMake(0.0f, bkView.frame.size.height - 1, bkView.frame.size.width, 1.0f);
        bottomBorder.backgroundColor = [UIColor blackColor].CGColor;
        [bkView.layer addSublayer:bottomBorder];
    }
2
Ravi Kumar

最初のレイアウトパスの後のみ、サイズを確認できます。または、ビューの実際の幅を取得した後、以下のメソッドを呼び出すだけです。

[yourView layoutIfNeeded];
1
Bhavesh Patel