2011-08-02 2 views
22

これにいくつか同様の質問がありましたが、私の具体的なニーズには対応していません。私はUIViewの最大使用可能なフレームサイズを返すジェネリックヘルパーメソッドを書くことができるようにしたいと思います。アプリケーションがステータスバー、ナビゲーションバー、タブバーのいずれかの組み合わせを持っているかどうかを考慮して、時間。UIViewの使用可能な最大フレームサイズをプログラムで決定します

[UIScreen mainScreen].applicationFrame

プロパティから得たことができ

+ (CGRect) maximumUsableFrame; 

またはステータスバーなしでサイズを取得するが、私は理解することはできません:

メソッドの定義はUIScreenの延長のようになりナビゲーションバーまたはタブバーが存在するかどうかを判断する方法を説明します。私は、アプリケーションのデリゲートでいくつかのグローバルフラグを維持することを考えましたが、これは本当に厄介なようであり、コードが一般的で再利用可能になるのを止めます。また、UIViewをパラメータとして渡し、ビューのウィンドウを取得してからrootViewControllerを呼び出し、ナビゲーションコントローラのプロパティが設定されているかどうかを確認しました。そうであれば、ナビゲーションコントローラが隠されているかどうかをチェックする。あなたが私に尋ねるならば、非常にclunky。

どのような考えにも感謝します。

デイブ

EDIT:

// Extension to UIViewController to return the maxiumum usable frame size for a view 
@implementation UIViewController (SCLibrary) 

- (CGRect) maximumUsableFrame { 

    static CGFloat const kNavigationBarPortraitHeight = 44; 
    static CGFloat const kNavigationBarLandscapeHeight = 34; 
    static CGFloat const kToolBarHeight = 49; 

    // Start with the screen size minus the status bar if present 
    CGRect maxFrame = [UIScreen mainScreen].applicationFrame; 

    // If the orientation is landscape left or landscape right then swap the width and height 
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { 
     CGFloat temp = maxFrame.size.height; 
     maxFrame.size.height = maxFrame.size.width; 
     maxFrame.size.width = temp; 
    } 

    // Take into account if there is a navigation bar present and visible (note that if the NavigationBar may 
    // not be visible at this stage in the view controller's lifecycle. If the NavigationBar is shown/hidden 
    // in the loadView then this provides an accurate result. If the NavigationBar is shown/hidden using the 
    // navigationController:willShowViewController: delegate method then this will not be accurate until the 
    // viewDidAppear method is called. 
    if (self.navigationController) { 
     if (self.navigationController.navigationBarHidden == NO) { 

      // Depending upon the orientation reduce the height accordingly 
      if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { 
       maxFrame.size.height -= kNavigationBarLandscapeHeight; 
      } 
      else { 
       maxFrame.size.height -= kNavigationBarPortraitHeight; 
      } 
     } 
    } 

    // Take into account if there is a toolbar present and visible 
    if (self.tabBarController) { 
     if (!self.tabBarController.view.hidden) maxFrame.size.height -= kToolBarHeight; 
    } 
    return maxFrame; 
} 
+1

NavigationBarコントロールやTabBarが表示されている場合は、高さをこのように見つけることができます: 'self.navigationController.navigationBar.frame.size.height;'と 'self.tabBarController.tabBar.frame.size.height'を。なぜタブバー高さの変数がkToolBarHeightと呼ばれていますか?=) – Alexander

+0

これをどのように使いたいかによって、少なくとも私の場合はnavControllerのフレーム原点も更新しました。そのため、ViewControllerで私のビューをどこに配置できるかがわかっていました。さもなければ、あなたはまだナビバーの下に終わることができます。 –

答えて

7

私はあなたが間違った場所にあなたの方法を入れていると思う:場合にはカレブの答えからのアイデアを取り入れ、これは誰にも有用です。 UIScreenは画面について知っていますが、何が表示されているかについては何も知っていません。にはの画面が表示されます。これはビューの管理を担当するView Controllerです。そのビューはメソッドが属する場所です。さらに、maxフレームは特定のView Controllerの構成に依存するため、これはインスタンスメソッドであり、クラスメソッドではありません。私はあなたの方法でのUIViewControllerにカテゴリを追加すべきだと思う:

- (CGRect) maximumUsableFrame; 

それはまだ、すべてのビューコントローラが利用可能な、かなり一般的だが、同時に、navigationControllertabBarControllerなどのビューコントローラのプロパティにアクセスすることができます。

+1

ポインタのおかげですべての良いものと感謝しています。エクステンションを書いて、どのように乗り遅れているかを教えてくれます。 –

+2

UIViewControllerにカテゴリを追加し、元の質問を編集してコードを追加していただき、ありがとうございました。乾杯。 –

9

applicationFrameを使用してください。 [[UIScreen mainScreen] applicationFrame]

これは私のスクリーンショットのものを切り抜くために使用する方法です。

ここにいくつかのサンプルコードがあります。

+0

これはなぜトップの答えではないのか分かりません。 – Isak

0

これを動作させるには、アプリケーションの境界線と方向スイッチを使用して、ステータスバーを削除する必要があると判断する必要がありました。これは最初に投稿されたコードのコピーと微調整です。私はこのアルゴリズムをnavbar/tabbar/noneとステータスバーとの組み合わせで実行する簡単なアプリを作って、すべてのシナリオで動作しました。

- (CGRect) maxFrame 
{ 
    // Start with the screen size minus the status bar if present 
    CGRect maxFrame = [UIScreen mainScreen].applicationFrame; 

    // the glass screen size 
    CGRect maxBounds = [UIScreen mainScreen].bounds; 


NSLog(@"MaxFrame for %d: (%f, %f, %f, %f)", self.interfaceOrientation, maxFrame.origin.x, maxFrame.origin.y, maxFrame.size.width, maxFrame.size.height); 
NSLog(@"MaxBounds for %d: (%f, %f, %f, %f)", self.interfaceOrientation, maxBounds.origin.x, maxBounds.origin.y, maxBounds.size.width, maxBounds.size.height); 


    // figure out the offset of the status bar 
    CGFloat statusBarOffset; 
    switch (self.interfaceOrientation) { 
     case UIInterfaceOrientationPortrait: 
      statusBarOffset = maxFrame.origin.y; 
     break; 
     case UIInterfaceOrientationPortraitUpsideDown: 
      statusBarOffset = maxBounds.size.height - maxFrame.size.height; 
     break; 
     case UIInterfaceOrientationLandscapeRight: 
     case UIInterfaceOrientationLandscapeLeft: 
      statusBarOffset = maxBounds.size.width - maxFrame.size.width; 
     break; 
    } 

    // If the orientation is landscape left or landscape right then swap the width and height 
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) { 
     CGFloat temp = maxBounds.size.height; 
     maxBounds.size.height = maxBounds.size.width; 
     maxBounds.size.width = temp; 
    } 

    // apply status bar to the top of the view 
    maxBounds.origin.y = statusBarOffset; 
    maxBounds.size.height -= statusBarOffset; 

    // Take into account if there is a navigation bar present and visible (note that if the NavigationBar may 
    // not be visible at this stage in the view controller's lifecycle. If the NavigationBar is shown/hidden 
    // in the loadView then this provides an accurate result. If the NavigationBar is shown/hidden using the 
    // navigationController:willShowViewController: delegate method then this will not be accurate until the 
    // viewDidAppear method is called) 
    if (self.navigationController && !self.navigationController.navigationBarHidden) { 
     NSLog(@"has nav bar"); 
     maxBounds.size.height -= self.navigationController.navigationBar.frame.size.height; 
     maxBounds.origin.y += self.navigationController.navigationBar.frame.size.height; 
    } 

    // Take into account if there is a toolbar present and visible 
    if (self.tabBarController && !self.tabBarController.view.hidden) { 
     maxBounds.size.height -= self.tabBarController.tabBar.frame.size.height; 
     NSLog(@"has tab bar"); 
    } 

NSLog(@"result for %d: (%f, %f, %f, %f)", self.interfaceOrientation, maxBounds.origin.x, maxBounds.origin.y, maxBounds.size.width, maxBounds.size.height); 
    return maxBounds; 
} 
+0

はmaxBounds.origin.y = statusBarOffsetをコメントする必要がありました。およびmaxBounds.origin.y + = self.navigationController.navigationBar.frame.size.height;これは別のアプリで使用されました。 –

関連する問題