2015-07-21 68 views
0

我一直在尋找同樣的問題,這麼長時間我可能在這裏失去了一個簡單的解決方案獲取當前可見的UIViewController的大小。從一個UIView

我創建了一個小型圖書館以提供粘在鍵盤像一個的iMessage不會(也就是不帶鍵盤隱藏)一個自定義的UIView:https://github.com/oseparovic/MessageComposerView

基本上我遇到的問題是,當用戶初始化的自定義視圖我想用下面的默認矩形視圖初始化:

CGFloat defaultHeight = 44.0; 
CGRect frame = CGRectMake(0, 
          [self currentScreenSize].height-defaultHeight, 
          [self currentScreenSize].width, 
          defaultHeight) 

這就需要currentScreenSize是UIView的內計算。我已經嘗試過所有這些都有其缺點的多個實現。由於這個MVC的破壞原則,似乎沒有好的解決方案。

有很多關於SO重複的問題,但大多數人認爲你有機會獲得代碼庫的這個自定義視圖不會,所以我正在尋找一個自包含的解決方案,其餘部分(例如應用程序的委託)。

下面是我使用的兩個主要實現:


NextResponder

該解決方案似乎是相當成功的在各種各樣的場景。它所做的就是獲得下一個響應的框架,該框架很方便地不包括導航欄或狀態欄,可用於給的UIView在屏幕的底部位置。

主要問題是在初始化時UIView內的self.nextRespondernil,這意味着它不能用於(至少我不知道)來設置初始幀。一旦視圖已經被初始化,並添加作爲一個子視圖雖然這似乎是各種用途重新定位一個魅力的工作。

- (CGSize)currentScreenSize { 
    // return the screen size with respect to the orientation 
    return ((UIView*)self.nextResponder).frame.size; 
} 

ApplicationFrame

這是我使用很長一段時間的解決方案,但它更笨重,有幾個問題。首先,通過使用applicationFrame,您必須處理導航欄高度,否則將會抵消視圖的位置。這意味着您必須確定它是否可見,獲取其高度並從currentSize中減去它。

不幸的是,獲取導航欄意味着您需要訪問UINavigationController,這不像訪問UIViewController那麼簡單。到目前爲止,我有最好的解決方案是包括以下currentNavigationBarHeight。我最近發現一個問題,但如果這將無法獲得導航欄的高度,如果一個UIAlertView中存在的[UIApplication sharedApplication].keyWindow.rootViewController將評估爲_UIAlertShimPresentingViewController

- (CGSize)currentScreenSize { 
    // there are a few problems with this implementation. Namely nav bar height 
    // especially was unreliable. For example when UIAlertView height was present 
    // we couldn't properly determine the nav bar height. The above method appears to be 
    // working more consistently. If it doesn't work for you try this method below instead. 
    return [self currentScreenSizeInInterfaceOrientation:[self currentInterfaceOrientation]]; 
} 

- (CGSize)currentScreenSizeInInterfaceOrientation:(UIInterfaceOrientation)orientation { 
    // http://stackoverflow.com/a/7905540/740474 

    // get the size of the application frame (screensize - status bar height) 
    CGSize size = [UIScreen mainScreen].applicationFrame.size; 

    // if the orientation at this point is landscape but it hasn't fully rotated yet use landscape size instead. 
    // handling differs between iOS 7 && 8 so need to check if size is properly configured or not. On 
    // iOS 7 height will still be greater than width in landscape without this call but on iOS 8 
    // it won't 
    if (UIInterfaceOrientationIsLandscape(orientation) && size.height > size.width) { 
     size = CGSizeMake(size.height, size.width); 
    } 

    // subtract the height of the navigation bar from the screen height 
    size.height -= [self currentNavigationBarHeight]; 

    return size; 
} 

- (UIInterfaceOrientation)currentInterfaceOrientation { 
    // Returns the orientation of the Interface NOT the Device. The two do not happen in exact unison so 
    // this point is important. 
    return [UIApplication sharedApplication].statusBarOrientation; 
} 

- (CGFloat)currentNavigationBarHeight { 
    // TODO this will fail to get the correct height when a UIAlertView is present 
    id nav = [UIApplication sharedApplication].keyWindow.rootViewController; 
    if ([nav isKindOfClass:[UINavigationController class]]) { 
     UINavigationController *navc = (UINavigationController *) nav; 
     if(navc.navigationBarHidden) { 
      return 0; 
     } else { 
      return navc.navigationBar.frame.size.height; 
     } 
    } 
    return 0; 
} 

有誰有關於我如何能最好地計算出的UIViewController大小建議從這個UIView中。我完全接受其他關於如何在初始化時將UIView粘貼到屏幕底部的建議,我可能忽略了這些建議。謝謝!

回答

0
+ (id) getCurrentUIViewController : (id)res { 
    if([res isKindOfClass:[UIViewController class]]) { 
     return res; 
    } 
    else if ([res isKindOfClass:[UIView class]]) { 
     return [Function getCurrentUIViewController:[res nextResponder]]; 
    } 
    else { 
     return nil; 
    } 
} 
+0

這可能是非常有用的,如果它的工作。謝謝,我會盡快嘗試 – alexgophermix