2015-07-21 63 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