UIImagePickerController interrompe a aparência da barra de status


137

No meu arquivo .plist, tenho " Exibir aparência da barra de status baseada em controlador " definida como NO. Mas depois UIImagePickerController, meu aplicativo se comporta como se a opção estivesse definida como YES.

No meu aplicativo, apresento um VC que apresenta um UIImagePickerController .

O problema acontece assim:

  • Depois que o seletor de fotos é apresentado, quando uma biblioteca de fotos é selecionada, a cor do texto da barra de status muda.
  • Então, uma vez UIImagePickerControllerdescartado, o espaçamento da barra de status muda para o restante do meu aplicativo e toda a barra de navegação para outros controladores é exibida sob a barra de status.

Existe uma maneira de resolver isso sem gerenciar a barra de status em meus controladores de exibição?


A resposta no meu caso estava ligada a controladores de exibição de crianças. Eu tive que recriá-los em vez de reutilizá-los.
Alex L

7
Isso realmente parece um bug do iOS 7, alguém entrou com uma denúncia na Apple?
Dan F

stackoverflow.com/questions/21225978/... pergunta semelhante com a solução simples
Ting Wu

Hey @AlexL, você sabe por que isso acontece?
Shabarinath Pabba

Respostas:


192

Nenhuma das soluções acima funcionou para mim, mas, combinando as respostas de Rich86man e iOS_DEV_09, eu tenho uma solução que trabalha consistentemente:

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

e

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

Em relação a esta solução impressionante. Para 2014 / iOS8, encontrei em alguns casos, você TAMBÉM precisa incluir prefersStatusBarHiddene, possivelmente, childViewControllerForStatusBarHiddenEntão ...

-(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...

Espero que ajude alguém


3
Este é o truque (como disse Rich86man): "Como o UIImagePickerController é um tipo de controlador de Navegação, você também está se configurando como o delegado do UINavigationController."
Beto

2
que tal depois de descartar UIImaegPicker ..? eu defino statusbar hide false, então o fundo fica preto.
Nitin Gohel

Você tem o plist configurado conforme a pergunta acima?
dpjanes

Você notou o problema ao usar o UIImagePickerControllerSourceTypePhotoLibrary, abrir um álbum e, em seguida, voltar um pouco e cancelar o gesto?
Kukosk

3
Isso funciona, embora a barra de status apareça dentro e fora de uma maneira muito irregular. Eu registrei um bug na Apple.
Jjxtra # 24/14

84

Eu enfrentei esse mesmo problema hoje. Aqui está a minha solução.

No controlador de exibição que chama o seletor de imagens, defina-se como o representante do seletor de imagens. (Você provavelmente já está fazendo isso)

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

Como UIImagePickerController é um tipo de controlador de Navegação, você também está se definindo como o delegado UINavigationController. Então :

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

Substitua UIStatusBarStyleLightContent pelo estilo que você estiver procurando.


10

A resposta aceita funcionará se você tiver a opção 'Exibir aparência da barra de status baseada no controlador' definida como NÃO no seu arquivo .plist. Se você realmente precisa controlar a barra de status em alguns outros controladores de exibição e ter essa opção definida como YES, a outra maneira de fazer com que UIImagePickerController se comporte corretamente é subclassificando-a

// .h
@interface MYImagePickerController : UIImagePickerController
@end

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

6

eu enfrentei o mesmo problema.

aqui está a minha solução. coloque isso no viewWillAppear do controlador de exibição do qual você está abrindo a seleção de imagem

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

[[UIApplication sharedApplication] setStatusBarHidden:YES];

}

4

Você pode tentar isso Eu acho que needsStatusBarApperanceUpdate funcionará.

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

4

Achei isso para oferecer manuseio adequado, há duas partes.

- (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];
...

o próprio UIImagePickerController apresenta os controladores de exibição, portanto, esse delegado funciona para todos os apresentadores da pilha.

o viewWillAppear assegura que o próprio controlador de exibição seja sempre redefinido sempre que um controlador de exibição apresentado for descartado acima dele.



2

Provavelmente é um bug. Resolvi o problema definindo "Visualizar aparência da barra de status baseada no controlador" definida como YES e em cada controlador de exibição colado no seguinte código:

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

Em seguida, meu aplicativo se comporta conforme o esperado.


2

Para ocultar a barra de status no UIImagePicker:

-

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

e quando UIImagePicker for dispensado para ocultar a barra de status no controlador de exibição, use o seguinte código:

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

    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}

2

tente isso ....

isso funcionará nos dois casos, ou seja, se você usa presentModalViewController e pushViewController

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

delegar métodos

-(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];
}

2

Todas as opções acima não funcionaram para mim. Resolvi o problema alterando o estilo de apresentação para:

imagePickerController.modalPresentationStyle = UIModalPresentationFullScreen;

2

Nenhuma das soluções acima funcionou para mim.

Apresento UIImagePickerController como controlador de exibição modal. Depois de descartar UIImagePickerController, o estado da barra de status era:

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

A solução que corrigiu o problema para mim foi restaurar o statusBarOrientation depois de descartar o UIImagePickerController:

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

...

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

2

Esse código me ajudou a personalizar o estilo da barra de status.

EDIT: esta solução funciona se "Exibir aparência da barra de status baseada no controlador" == SIM

@implementation UIImagePickerController (IOS7_StatusBarStyle)

-(UIViewController*)childViewControllerForStatusBarStyle
{
   return nil;
}

-(UIStatusBarStyle)preferredStatusBarStyle
{
   return UIStatusBarStyleLightContent;
}

@end

2

Todas as respostas acima estão ok e podem ajudar.

Eu tive o mesmo problema ao gerenciar o aplicativo executado em diferentes versões do 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];

Em seguida, no delegado:

- (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];
}

2

Mais uma solução que pode funcionar em algumas situações.

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

1

Você tentou ligar [self setNeedsStatusBarAppearanceUpdate]quando o controlador de exibição em exibição reapareceu?


Provavelmente, é um bug da época - eu arquivava um radar com um projeto de exemplo e voltava ao antigo sistema de gerenciamento da barra de status :( #
5500 Ash

1

Tento ocultar a barra de status no UIImagePickerController no iOS7, mas ainda não sei como fazer isso. eu uso

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

no ViewController que chama o UIImagePickerController e defina "Exibir aparência da barra de status baseada em controlador = NÃO" no arquivo plist. Espero que isso possa ajudar.


1

tente isto:

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

e no protocolo implementar, use o seguinte:

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

1

Isso resolveu para mim ...:

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

1

Nada aqui resolveu especificamente o problema em que eu estava tendo (e talvez o OP também estivesse), então pensei em compartilhar minha resposta. Em vez de ocultar a barra de status, que eu acho que é uma solução de buggy (notei que algumas vezes deixava meu aplicativo em um estado em que a barra de status estava oculta quando não deveria). Em vez disso, optei por tentar jogar bem com oUIStatusBarStyles .

Quando o UIImagePickerController tem sua visualização apresentada, defino o estilo da barra de status como padrão, pois a cor de plano de fundo padrão é um cinza claro.

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

Em seguida, quando o seletor de imagens é descartado, eu o coloco de volta em 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];
}

1

Nesse caso, estamos usando 2 etapas

Na primeira etapa: adicione info.plist: "Exibir a aparência da barra de status com base no controlador" com o valor "NO"

Na segunda etapa: use / chame esse código com o delegado de UIImagePickerController

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

No caso do IOS-7, adicione mais uma função

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

1

A partir do iOS 8.1, parece que eles finalmente corrigiram esse bug! Consegui remover todas as soluções alternativas que empreguei do meu código.


1

Usando o comportamento padrão do iOS 8, eu estava tendo problemas com a barra de status aparecendo quando queria ocultá-la.

A solução que encontrei foi que, logo após ligar presentPopoverdo meu controlador de exibição, fiz:

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

Eu também tive que adicionar isso ao meu controlador de exibição principal:

- (UIViewController *)childViewControllerForStatusBarHidden
{
    return nil;
}

1

Então, eu tive esse problema e pude resolvê-lo simplesmente implementando uma única função de delegado. O fundo da minha barra de status é preto e, portanto, o UIStatusBarStyle para o meu aplicativo é .LightContent. Quando apresentei o UIImagePickerController para selecionar uma foto no armazenamento do dispositivo, a barra de status estava boa. No entanto, ao clicar em um diretório como "Rolo da câmera" ou "Favoritos", pressionando efetivamente a pilha de navegação, a barra de status desapareceu. Ao selecionar uma foto, não havia barra de status; ao descartar outro controlador de exibição modal, apenas a bateria estava presente, indicando que o restante da barra de status também pode estar preto.

Tentei algumas das outras soluções, como estender o UIImagePickerController, mas no Swift, você não pode substituir usando extensões. Tentei subclassificar UIImagePickerController e tentei ocultar sua barra de status em viewWillAppear () e mostrar novamente a barra de status em viewWillDisappear. Consegui ver a barra de status oculta com uma animação .Slide, mas como a barra de status estava invisível ao selecionar um diretório, não pude ver a barra de status reexibida. Mais uma vez, a bateria verde voltou com o restante da barra de status invisível ao descartar um controlador de exibição modal. Também tentei substituir preferersStatusBarHidden (), mas essa função nunca foi chamada, então tentei chamar setNeedsStatusBarAppearanceUpdate () para garantir que prefersStatusBarHidden () seja chamado pelo sistema, mas ainda não seja chamado. Além disso, existe a sugestão de definir a barra de status para ser oculta no método delegado navigationController willShowViewController. Mais uma vez, tudo isso faz é ocultar a barra de status, o que não resolve o problema. Como se vê, parece que o estilo da barra de status é alterado ao empurrar para a pilha de navegação do UIImagePickerController. Para resolver o problema completamente, não precisei escrever extensões ou subclasses UIImagePickerController. Tudo que você precisa fazer é definir o delegado e o estilo da barra de status para permanecer o mesmo. Esta adição tornou como se o problema nunca existisse. parece que o estilo da barra de status é alterado ao enviar para a pilha de navegação do UIImagePickerController. Para resolver o problema completamente, não precisei escrever extensões ou subclasses UIImagePickerController. Tudo que você precisa fazer é definir o delegado e o estilo da barra de status para permanecer o mesmo. Esta adição tornou como se o problema nunca existisse. parece que o estilo da barra de status é alterado ao enviar para a pilha de navegação do UIImagePickerController. Para resolver o problema completamente, não precisei escrever extensões ou subclasses UIImagePickerController. Tudo que você precisa fazer é definir o delegado e o estilo da barra de status para permanecer o mesmo. Esta adição tornou como se o problema nunca existisse.

let pickerController = UIImagePickerController()
pickerController.delegate = self

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

-1

Na verdade, encontrei uma maneira melhor de definir a cor de fundo da barra de status no Seletor de Imagens. Basicamente, você precisa definir a backgroundImage da barra de navegação como nula, porque o padrão no Image Picker tem uma backgroundImage como uma imagem branca.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.