UIImagePickerController нарушает внешний вид строки состояния

В моем .plist файле у меня есть "Просмотр состояния панели управления на основе контроллера", установленного на NO. Но после UIImagePickerController мое приложение ведет себя так, как будто для параметра установлено значение YES.

В моем приложении я представляю VC, который представляет UIImagePickerController.

Проблема происходит следующим образом:

  • После выбора фотосъемки, когда выбрана фотобиблиотека, цвет текста строки состояния изменяется.
  • Затем один раз UIImagePickerController отклоняется, интервал строки состояния изменения для остальной части моего приложения и всей панели навигации для других контроллеров отображаются в строке состояния.

Есть ли способ решить эту проблему без управления панелью состояния в контроллерах моего представления?

Ответ 1

Ни одно из вышеперечисленных решений не работало для меня, но, объединив ответы Rich86man и iOS_DEV_09, у меня есть постоянно работающее решение:

UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;

и

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}

Относительно этого удивительного решения. Для 2014/iOS8 я обнаружил, что в некоторых случаях вам также нужно добавить prefersStatusBarHidden и, возможно, childViewControllerForStatusBarHidden So...

-(void)navigationController:(UINavigationController *)navigationController
        willShowViewController:(UIViewController *)viewController
        animated:(BOOL)animated
    {
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    }

-(BOOL)prefersStatusBarHidden   // iOS8 definitely needs this one. checked.
    {
    return YES;
    }

-(UIViewController *)childViewControllerForStatusBarHidden
    {
    return nil;
    }

-(void)showCamera
    {
    self.cameraController = [[UIImagePickerController alloc] init];
    self.cameraController.delegate = (id)self; // dpjanes solution!
    etc...

Надеюсь, что это поможет кому-то

Ответ 2

Сегодня я столкнулся с такой же проблемой. Вот мое решение.

В контроллере представления, который вызывает подборщик изображений, задайте себя как делегат изображения Picker. (Возможно, вы уже это делаете)

UIImagePickerController* imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;

Поскольку UIImagePickerController является типом навигационного контроллера, вы также устанавливаете себя как делегат UINavigationController. Тогда:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

Замените UIStatusBarStyleLightContent на любой стиль, который вы ищете.

Ответ 3

Принятый ответ будет работать, если в вашем файле .plist установлен "Просмотр состояния на основе контроллера на основе контроллера", установленный в "НЕТ". Если вам действительно нужно контролировать строку состояния в некоторых других контроллерах представлений и установить этот параметр на YES, другой способ заставить UIImagePickerController вести себя правильно, это подклассифицировать его

// .h
@interface MYImagePickerController : UIImagePickerController
@end

// .m
@implementation MYImagePickerController
- (UIStatusBarStyle)preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent; // change this to match your style
}
@end

Ответ 4

i столкнулся с той же проблемой.

вот мое решение. поместите это в viewWillAppear контроллера вида, из которого вы открываете изображение pickerview

-(void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:YES];

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}

Ответ 5

Можете ли вы попробовать это. Я думаю, что needStatusBarApperanceUpdate будет работать.

1 -Set UIViewControllerBasedStatusBarAppearance to NO.
2- Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
3- [self setNeedsStatusBarAppearanceUpdate];

Ответ 6

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

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
}


- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque];
...

сам UIImagePickerController представляет контроллеры представлений, поэтому этот делегат работает для всех докладчиков в стеке.

viewWillAppear обеспечивает, чтобы этот контроллер представления всегда был reset всякий раз, когда диспетчер представления представления отклоняется над ним.

Ответ 7

Это, вероятно, ошибка. Я решил проблему, установив для параметра "Просмотр состояния панели управления на основе контроллера" значение "ДА" и в каждом вставке контроллера просмотра в следующем коде:

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Затем мое приложение ведет себя так, как ожидалось.

Ответ 8

Для скрытия строки состояния в UIImagePicker:

-

 (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

и когда UIImagePicker отклоняется, чтобы скрыть строку состояния в контроллере View, используйте следующий код:

-(void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:YES];

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}

Ответ 9

попробуйте это....

это будет работать в обоих случаях, если вы используете presentModalViewController и pushViewController

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;

методы делегирования

-(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary*)info
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:^{}];
}


- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:nil];
}

Ответ 10

У меня была та же проблема. Добавить в info plist: "Просмотреть внешний вид строки на основе контроллера" со значением "НЕТ"

Пример здесь fooobar.com/questions/44132/...

Это решение работает для меня.

Ответ 11

Ни один из вышеперечисленных решений не работал у меня.

Я представляю UIImagePickerController в качестве модального контроллера. После отклонения UIImagePickerController состояние состояния состояния:

[UIApplication sharedApplication].statusBarOrientation = 0 (UIDeviceOrientationUnknown)
[UIApplication sharedApplication].statusBarFrame = { 0, 0, 0, 0}

Решение, которое устранило проблему для меня, - это восстановление statusBarOrientation после отклонения UIImagePickerController:

UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
[self.viewController presentViewController:cameraUI animated:true completion:^(void){ }];

...

[self.viewController dismissViewControllerAnimated:animated completion:^(void){
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
}];

Ответ 12

Этот код помог мне настроить стиль строки состояния.

EDIT: это решение работает, если "Просмотреть статус панели управления на основе контроллера" == YES

@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end

Ответ 13

Все ответы выше в порядке и могут помочь.

У меня была такая же проблема, связанная с управлением приложением, запущенным в разных версиях iOS.

UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];

if(IS_IOS8_AND_UP) {
    imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;
} else {
    imagePickerController.modalPresentationStyle = UIModalPresentationCurrentContext;
}

imagePickerController.delegate = self;
[self presentViewController:imagePickerController animated:YES completion:nil];

Затем в делегате:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
    /* Cancel button color  */
    _imagePicker.navigationBar.tintColor = <custom_color>
    /* Status bar color */
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
}

Ответ 14

Еще одно решение, которое может работать в некоторых ситуациях.

let imagePicker =  UIImagePickerController()
imagePicker.sourceType = .PhotoLibrary
imagePicker.navigationBar.barStyle = .Black

Ответ 15

Пробовали ли вы вызов [self setNeedsStatusBarAppearanceUpdate], когда появился ваш контроллер представления?

Ответ 16

Я пытаюсь скрыть строку состояния в UIImagePickerController в iOS7, но я до сих пор не знаю, как это сделать. Я использую

- (void)viewWillAppear:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES
                                        withAnimation:UIStatusBarAnimationNone];
}

в ViewController, вызывающем UIImagePickerController, и установите "Просмотреть строку состояния на основе контроллера = NO" в файле plist. Надеюсь, это поможет.

Ответ 17

попробуйте следующее:

UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;

и в реализации протокола, используйте это:

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
}

Ответ 18

Это решило это для меня...:

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [[UIApplication sharedApplication] setStatusBarHidden:YES];
    [picker dismissViewControllerAnimated:YES completion:nil];
}

Ответ 19

Ничто здесь конкретно не зафиксировало проблему в том, что у меня было (и, возможно, что у OP тоже было), поэтому я решил поделиться своим ответом. Вместо того, чтобы скрывать строку состояния, которая, по моему мнению, является ошибочным решением (я заметил, что иногда она оставит мое приложение в состоянии, когда строка состояния была скрыта, когда этого не должно быть). Вместо этого я решил попробовать играть с UIStatusBarStyles.

При представлении представления UIImagePickerController я установил стиль строки состояния по умолчанию, поскольку цвет фона по умолчанию светло-серый.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
}

Затем, когда сборщик изображений уволен, я верну его обратно к UIStatusBarStyleLightContent.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    //work

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

    [self dismissViewControllerAnimated:YES completion:NULL];
}

- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{ 
    //work

    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];

    [self dismissViewControllerAnimated:YES completion:NULL];
}

Ответ 20

В этом случае мы используем 2 шага

На первом шаге:               Добавить в info.plist: "Просмотр состояния панели состояния на основе контроллера" со значением "НЕТ"

На втором шаге: используйте/вызовите этот код с делегатом UIImagePickerController

 - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
     if([navigationController isKindOfClass:[UIImagePickerController class]])
         [[UIApplication sharedApplication] setStatusBarHidden:YES]; 
 }

В случае IOS-7 добавьте еще одну функцию

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Ответ 21

Все вышеизложенное не помогло мне. Я решил проблему, изменив стиль презентации:

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;

Ответ 22

Как и в iOS 8.1, похоже, что они наконец исправили эту ошибку! Я смог удалить все обходные пути, которые я использовал в своем коде.

Ответ 23

Используя поведение IOS 8 по умолчанию, у меня возникали проблемы со строкой состояния, появляющейся, когда я хотел, чтобы она была скрыта.

Решение, которое я нашел, состояло в том, что непосредственно после вызова presentPopover из моего контроллера представления я сделал:

    [self performSelector:@selector(setNeedsStatusBarAppearanceUpdate) withObject:nil afterDelay:0.01];

Мне также пришлось добавить это в мой главный контроллер представления:

- (UIViewController *)childViewControllerForStatusBarHidden
{
    return nil;
}

Ответ 24

Итак, у меня была эта проблема, и я смог ее решить, просто выполнив одну функцию делегата. Фон моей строки состояния черный, поэтому UIStatusBarStyle для моего приложения является .LightContent. Когда я представил UIImagePickerController для выбора фотографии из памяти устройства, строка состояния была в порядке. Однако, щелкнув в каталоге, таком как "Camera Roll" или "Favorites", фактически нажав на стек навигации, строка состояния исчезла. После выбора фотографии не было ни одной строки состояния; после отклонения другого модального контроллера, только батарея присутствовала, указав, что остальная часть строки состояния также может быть черной.

Я попробовал некоторые другие решения, такие как расширение UIImagePickerController, но в Swift вы не можете переопределить использование расширений. Затем я попытался подклассифицировать UIImagePickerController и попытался скрыть свою строку состояния на viewWillAppear() и отобразить строку состояния в представленииWillDisappear. Я смог увидеть, что строка состояния скрыта с анимацией .Slide, но поскольку строка состояния была невидимой при выборе каталога, я не смог увидеть строку состояния. Опять же, зеленая батарея вернулась с остальной частью строки состояния, невидимой при отключении модального контроллера. Я также попытался переопределить prefersStatusBarHidden(), но эта функция никогда не вызывалась, поэтому я попытался вызвать setNeedsStatusBarAppearanceUpdate(), чтобы гарантировать, что prefersStatusBarHidden() вызывается системой, но она все еще не вызывается. Кроме того, есть предложение, чтобы строка состояния была скрыта в методе делегата navigationController willShowViewController. Еще раз все это скрывает строку состояния, которая не решает проблему. Как оказалось, кажется, что стиль строки состояния изменяется при нажатии на навигационную стекю UIImagePickerController. Чтобы полностью решить проблему, мне не пришлось писать расширения или подкласс UIImagePickerController. Все, что вам нужно сделать, это установить делегат и установить стиль строки состояния, чтобы он остался прежним. Это добавление делало это так, как будто проблема никогда не существовала.

let pickerController = UIImagePickerController()
pickerController.delegate = self

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
        UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
    }

Ответ 25

Я действительно нашел лучший способ установить цвет фона в строке состояния в Image Picker. В основном вам нужно установить backgroundImage из navigationBar в nil, потому что по умолчанию в Image Picker есть backgroundImage как белое изображение.