2009-06-29 18 views
8

私はUINavigationControllerをランドスケープモードに回転でき、新しいUIViewControllerを初期化してスタックにプッシュします。 UIViewController'sviewDidLoad私はちょうどself.view.frame.sizeを印刷します。フレームサイズがランドスケープモードで変更されない

UINavigationControllerがポートレートモードの場合、View Controllerは{320、460}を印刷します。ただし、ナビゲーションコントローラが風景の場合、フレームサイズはまったく同じです。 (2番目のケースでは、UIViewControllerは電話機がすでにランドスケープモードの間に初期化されています)。

ビューのフレームサイズを回転させるべきではありませんか?そして、もし私がどのようにして数字をハードコーディングせずに正しいフレームサイズを見つけることができないのであれば?

答えて

6

フレームを横向きモードで使用することはできません。境界と中心の組み合わせを使用する必要があります。フレームはそれらの組み合わせを使用して生成され、非恒等変換が適用されているとき(風景の中にあるように)、それはちょっと変わってしまいます。

+0

あなたは手の込んだていただけますか?境界は両方の場合とも同じ{320、460}であり、中心も変わらない。 – user130444

+0

フレームのサイズが変更されない理由を尋ねる場合は、スプリングとストラットが適切に設定されていますか?それが最初にチェックすることです。 –

+0

はい、私のビューは回転したときにサイズが変わります。唯一の問題は、風景のときに作成されるときです。 – user130444

3

まず、適切な自動サイズ変更マスクを使用して自動的にサイズを変更するようにビューを設定する必要があります。 このビューはコントローラー自体のサイズに適応します。

あなたはこれをNSLogで自分で確認できます。しかし、loadViewに入れないでください。これは早すぎます。これをviewWillAppearに入れます。

ビューの自動サイズ変更マスクをInterface Builderで設定する場合は、「属性」インスペクタの「シミュレートされたインターフェイス要素」をオフにする必要があります。これらのいずれかがオンの場合は、サイズインスペクタで自動サイズ変更マスクを変更できません。

+1

viewWillAppearに関するヒントをありがとう。デニスとデビッドに+1 – David

+0

+1これは、ランドスケープモードで作成されたコントローラでのこのサイジングの問題に対する受け入れられた答えです。 –

1

これは苦痛であり、iOS 4.2 for iPadsではまだ当てはまります。私がこれを解決する方法はUIViewをサブクラス化してUIViewControllerに関連付けることです。私はインターフェースビルダーでこれをやったが、私はこれを何らかの形でコード内で行うこともできると思う。インターフェイスビルダーでUIViewControllerのUIViewを選択し、インスペクタウィンドウの右上にある(i)アイコンをクリックします。クラスIDの下でポップアップを押し、下のUIViewサブクラスを選択しました。

アプローチは、このUIViewのサブクラスは、layoutSubviewsメソッドをオーバーライド次UIViewControllerを見つけ、それは(このビューのビューコントローラのUIViewControllerサブクラスで実装する必要がメソッドである)reactToLayoutメソッドを実装かどうかを決定することです。最初にUIViewControllerにreactToLayoutメソッドが存在する場合は、それが呼び出されます。

ビューコントローラでreactToLayout方法は、1つのビューのフレームは、この時点で適切に設定されているので、(viewWillAppearViewDidLoadとは異なり、あるいはviewDidAppear)が正常に行うことができるようになりますどの行う必要があるものは何でもありません。オリエンテーションやフレームが変わるたびに呼び出す方法があります。それは痛みですが、レイアウトされた最後のフレームとビューコントローラの内部変数に配置された最後の方向を保存します。新しい方向付けまたはフレーム変更方法の内部レイアウトは、これらをビューの現在のフレーム、要求されたまたは現在の方向と比較して、不必要にレイアウトを何度も繰り返さないようにします。

UILayoutSubviewsView.h

#import <UIKit/UIKit.h> 

@interface UILayoutSubviewsView : UIView { 
} 

@end 

UILayoutSubviewsView:

は、ここでは、コードです。メートル

#import "UILayoutSubviewsView.h" 

// Create this to avoid a warning that this method does not exist for UIViewControllers 
// this is OK since we check to see that it does exist before invoking it 
@interface UIViewController(UndocumentedMethodForUIViewController) 
-(void) reactToLayout; 
@end 

@implementation UILayoutSubviewsView 

// Pass this up to our view controller if it supports the reactToLayout method 
// (this is the whole reason for the class) 
-(void) layoutSubviews { 
    [super layoutSubviews]; 

    // Look for the first next responder that is a UIViewController 
    UIViewController *ourViewController = nil; 
    id myNextResponder = [self nextResponder]; 
    while (myNextResponder != nil && ourViewController == nil) { 
    if ([myNextResponder isKindOfClass:[UIViewController class]]) { 
     ourViewController = myNextResponder; 
    } 
    else { 
     myNextResponder = [myNextResponder nextResponder]; 
    }  
    } 

    // If we got a view controller, then see if it supports the reactToLayout method 
    if (ourViewController != nil) { 
    if ([ourViewController respondsToSelector:@selector(reactToLayout)]) { 

     // Invoke the view controller's reactToLayout method 
     [ourViewController reactToLayout]; 

    } 
    } 

} 

@end 

YourViewController.h

#import <UIKit/UIKit.h> 

@interface YourViewController : UIViewController { 
    CGRect lastLayedOutFrame; 
    UIInterfaceOrientation lastLayedOutOrientation; 
} 

#pragma mark - 
#pragma mark Instance Methods 
-(id) init; 
-(void) reactToLayout; 

@end 

YourViewController.m

私は私のために仕事をする あなたはcurrentSizeを使用することができます簡単な解決策があると思います
#import "YourViewController.m" 

#pragma mark Private Interface Category 
@interface YourViewController() 
-(void) setViewForCurrentFrameAndRequestedOrientation:(UIInterfaceOrientation) interfaceOrientation; 
@end 

@implementation YourPadViewController 

-(id) init { 

    // First our super then set ourselves up 
    if (self = [super initWithNibName:@"YourViewController" bundle:nil]) { 

    // Initialize some basic stuff 
    lastLayedOutFrame = CGRectZero; 
    lastLayedOutOrientation = UIDeviceOrientationUnknown; 

    } 

    return self; 
} 

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

    // Make sure we're showing the right stuff in the right place 
    [self setViewForCurrentFrameAndRequestedOrientation:UIDeviceOrientationUnknown]; 

} 

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

    // Make sure we're showing the right stuff in the right place 
    [self setViewForCurrentFrameAndRequestedOrientation:UIDeviceOrientationUnknown]; 

} 

-(void) reactToLayout { 

    // Make sure we're showing the right stuff in the right place 
    [self setViewForCurrentFrameAndRequestedOrientation:UIDeviceOrientationUnknown]; 

} 

#pragma mark - 
#pragma mark Rotation Support 
-(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation { 
    return YES; 
} 

// This is called right before the actual rotation 
-(void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation) interfaceOrientation duration:(NSTimeInterval) duration { 
    [super willAnimateRotationToInterfaceOrientation:interfaceOrientation duration:duration]; 

    // Make sure we're showing the right stuff in the right place 
    [self setViewForCurrentFrameAndRequestedOrientation:interfaceOrientation]; 

} 

// Make the necessary adjustments for the different view orientations 
-(void) setViewForCurrentFrameAndRequestedOrientation:(UIInterfaceOrientation) interfaceOrientation { 

    // Set up the requested orientation (need this to handle the Unknown case) 
    UIInterfaceOrientation requestedOrientation; 
    if (interfaceOrientation != UIDeviceOrientationUnknown) { 
    requestedOrientation = interfaceOrientation; 
    } 
    else { 
    requestedOrientation = [[UIDevice currentDevice] orientation]; 
    } 

    // See if we have anything to do 
    if (!(CGRectEqualToRect(self.view.frame, lastLayedOutFrame) && lastLayedOutOrientation == requestedOrientation)) { 

    // Do whatever needs to be done 

    // Record our last layed out frame and orientation 
    lastLayedOutFrame = self.view.frame; 
    lastLayedOutOrientation = requestedOrientation; 

    } 

} 
0

こんにちは一人一 self.view.frame.sizeの代わりに

yo urClass.h

yourClass.m

@interface yourClass : UIViewController { 
    CGSize currentSize; 
} 
@property (nonatomic, readwrite)CGSize currentSize; 
@end 

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration           
{ 
    if (toInterfaceOrientation != self.interfaceOrientation) { 
     CGSize newSize; 
     // 20 is the status bar height 
     newSize.width = self.view.bounds.size.height + 20; 
     newSize.height = self.view.bounds.size.width - 20; 
     currentSize = newSize; 
     //any other necessary code 
    } 
} 
+0

素晴らしい回避策;)しかし、self.interfaceOrientationは私に悪いアクセスを与える..?! –

関連する問題