3

在我的应用程序中,我通过简单地缩放整个窗口以适应剩余的屏幕空间来处理状态栏框架的变化:

- (void)application:(UIApplication *)application willChangeStatusBarFrame:
    (CGRect)newStatusBarFrame {

    UIView* window = [UIApplication sharedApplication].keyWindow;

    [UIView animateWithDuration:1 / 3.f animations:^{
        CGFloat heightDifference = newStatusBarFrame.size.height - 
            kWXDefaultStatusBarHeight;

        [window setTransform:CGAffineTransformMakeScale(1.f, 
            heightScaleForCallStatusBar())];
        [window setFrame:CGRectOffset(window.frame, 0, heightDifference - 
            kWXDefaultStatusBarHeight / 2)];
    }];
}

这可行,但如果窗口在调用期间按比例缩小,并且我提供了一个带有 的视图控制器-presentViewController:animated:completion:,则新控制器不使用按比例缩放的坐标系,它使用未按比例缩放的坐标系,并且 UI 会损坏。知道如何让窗口.transform转移到呈现的新视图控制器吗?

或者,是否有另一种方法来处理通话状态栏而不重新排列我的所有 UI 元素?

4

1 回答 1

3

每个视图控制器都会将其视图的框架设置为可用空间。处理此问题的最简单方法是确保视图的弹簧和支柱或自动布局属性允许视图的压缩或扩展。随着 iPhone 世界现在包括多种屏幕尺寸,这是一个很好的通用做法。

但是,如果您打算在视图上使用变换来处理大小调整,则可以-viewWillLayoutSubviews在视图控制器(可能在公共基类中)中实现以在视图控制器的根视图上设置变换。

编辑

经调查,通话中状态栏的更改似乎不会导致-viewWillLayoutSubviews被调用。但是,以下代码(在通用视图控制器基类中)对我有用:

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(statusFrameChanged:)
                                                 name:UIApplicationWillChangeStatusBarFrameNotification
                                               object:nil];
}

- (void)viewDidUnload
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:UIApplicationWillChangeStatusBarFrameNotification
                                                  object:nil];
    [super viewDidUnload];
}

- (void)statusFrameChanged:(NSNotification*)note
{
    CGRect statusBarFrame = [note.userInfo[UIApplicationStatusBarFrameUserInfoKey] CGRectValue];
    CGFloat statusHeight = statusBarFrame.size.height;

    UIScreen *screen = [UIScreen mainScreen];
    CGRect viewRect = screen.bounds;

    viewRect.size.height -= statusHeight;
    viewRect.origin.y = statusHeight;
    self.view.frame = viewRect;
    [self.view setNeedsLayout];
}

- (void)viewWillLayoutSubviews
{
    [super viewWillLayoutSubviews];

    CGRect baseFrame = self.view.frame;
    // 548.0 is the full height of the view.  Update as necessary.
    CGFloat scale = self.view.frame.size.height / 548.0;
    [self.view setTransform:CGAffineTransformMakeScale(1.0, scale)];
    self.view.frame = baseFrame;
}
于 2013-04-08T22:30:44.213 回答