it-swarm.com.ru

UIViewController's предпочтенияStatusBarHidden не работает

Я пытаюсь сделать строку состояния для одного из моих контроллеров представления скрытой (когда отображается модально). Когда я представляю контроллер представления, строка состояния должна быть скрыта, а затем возвращена при отклонении.

Я добавил следующий код в представленный контроллер представления

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Я также установил ключи в файле Info.plist следующим образом:

<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>

Насколько я понимаю, это должно быть все, что требуется для этой работы. 

Я также использую пользовательский контроллер анимации для представления, который соответствует протоколу UIViewControllerAnimatedTransitioning. В реализации animateTransition: я попытался вручную вызвать prefersStatusBarHidden, а затем setNeedsStatusBarAppearanceUpdate, чтобы убедиться, что выполняется вызов, но строка состояния остается.

Любые идеи, почему это происходит, будут оценены. Я искал StackOverflow, но, похоже, ни у кого не было этой проблемы, все принятые ответы относятся к вызову setNeedsStatusBarAppearanceUpdate, который я уже делаю.

EDIT- Код ниже теперь, кажется,РАБОТАЕТпо желанию 

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext
{
    if (self.isPresenting) {
        UIView *containerView = [transitionContext containerView];

        UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

        toViewController.view.frame = containerView.frame;

        [containerView addSubview:toViewController.view];

        // Ask the presented controller whether to display the status bar
        [toViewController setNeedsStatusBarAppearanceUpdate];

        [UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
            toViewController.view.alpha = 1.0f;
            fromViewController.view.alpha = 0.0f;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
    else {
        // do the reverse
        UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
        UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

        [UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionCurveEaseIn animations:^{
            toViewController.view.alpha = 1.0f;
            fromViewController.view.alpha = 0.0f;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
            // Once dismissed - ask the presenting controller if the status bar should be presented
            [toViewController setNeedsStatusBarAppearanceUpdate];
        }];
    }
}

....

// PresentingController.m
- (BOOL)prefersStatusBarHidden
{
    if (self.presentedViewController) {
        return YES;
    }
    return NO;
}

// PresentedController.m
- (BOOL)prefersStatusBarHidden
{
    return YES;
}
40
Taz

В iOS7 на самом деле есть новое свойство для UIViewController, которое называется modalPresentationCapturesStatusBarAppearance. Ссылка на Apple iOS.

Значением по умолчанию является НЕТ.

Когда вы представляете контроллер представления, вызывая presentViewController: animated: завершение: метод, управление внешним видом строки состояния переносится из представления в представленный контроллер представления, только если значение modalPresentationStyle представленного контроллера равно UIModalPresentationFullScreen. Установив для этого свойства значение YES, вы задаете внешний вид строки состояния представленных контроллеров представления, даже если они представлены не в полноэкранном режиме.

Система игнорирует значение этого свойства для полноэкранного контроллера представления.

Поэтому для любого презентационного стиля, отличного от обычного полноэкранного режима (например, UIModalPresentationCustom), этот должен быть установлен, если вы хотите захватить строку состояния. Чтобы использовать, все, что вам нужно сделать, это установить его на YES на представляемом контроллере представления:

toVC.modalPresentationCapturesStatusBarAppearance = YES;
106
David Liu

Я собираюсь предположить (образованный, но все еще предположение), что это потому, что когда вы делаете представленный контроллер представления, используя пользовательский переход, в iOS 7, старый контроллер представления все еще там. Поэтому, вероятно, это все еще имеет право голоса.

Вы можете даже поставить точку останова в itsprefersStatusBarHidden, чтобы увидеть; вам придется реализовать его, если он не реализован. Значение по умолчанию - НЕТ, поэтому, если к нему обратиться, это объяснит ваш результат.

Если я прав, вам потребуется реализовать prefersStatusBarHidden контроллера представления old, чтобы дать два разных ответа, в зависимости от того, имеет он presentedViewController или нет.

EDITТеперь я это подтвердил. Это даже хуже, чем я думал; в моем тестировании prefersStatusBarHidden контроллера второго представления вообще не вызывался. Все это в руках контроллера первого вида. Это имеет смысл, потому что, как я уже сказал, первый контроллер представления никогда не исчезает; в случае пользовательской анимации представления второй контроллер представления подчиняется первому, поскольку второй вид может частично зависать над первым видом.

Таким образом, вам придется полностью управлять строкой состояния с первого контроллера представления. Вы можете вызвать его prefersStatusBarHidden, вызвав [self setNeedsStatusBarAppearanceUpdate]. Вам нужно будет дать другой ответ в зависимости от обстоятельств. Это может быть немного сложно. Вот простая реализация, но она может не охватывать все случаи:

// ViewController1:

-(void)setHide:(NSNumber*)yn {
    self->hide = [yn boolValue]; // a BOOL ivar
    [self setNeedsStatusBarAppearanceUpdate];
}
-(BOOL)prefersStatusBarHidden {
    return self->hide;
}
- (IBAction)doButton:(id)sender {
    self->hide = YES;
    [self setNeedsStatusBarAppearanceUpdate];
    [self presentViewController:[ViewController2 new] animated:YES completion:nil];
}

// ==========

// ViewController2:

- (IBAction)doButton:(id)sender {
    [self.presentingViewController setValue:NO forKey:@"hide"];
    [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
17
matt

Вы можете добавить это в info.plist

«Просмотреть внешний вид строки состояния на основе контроллера» и установить значение «Нет»

0
zuyao88