Обработка приложения:willChangeStatusBarFrame:

В моем приложении я управляю изменением рамки строки состояния, просто масштабируя все окно, чтобы оно поместилось в оставшееся пространство экрана:

- (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:, новый контроллер не использует масштабированную систему координат, он использует немасштабированную систему, и пользовательский интерфейс нарушается. Любая идея, как получить окно .transform перейти на новые представления контроллеров, которые представлены?

В качестве альтернативы, есть ли другой способ обработки строки состояния в вызове, не переставляя все мои элементы пользовательского интерфейса?

1 ответ

Каждый контроллер представления будет иметь рамку своего представления, установленную на доступное пространство. Самый простой способ справиться с этим - убедиться, что свойства springs-and-Struts или autolayout вашего вида допускают сжатие или расширение представления. Сейчас, когда мир 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;
}
Другие вопросы по тегам