Esmaecer uma tela inicial do iOS

Recentemente, tive a necessidade de abrir a tela inicial e fazer crossfade com o conteúdo do aplicativo, principalmente para evitar mudanças grandes (e irritantes) ao lidar com temas escuros. Minhas telas iniciais não sabem em que tema você está, então se você estiver em um tema escuro e minha tela inicial for branca, haverá uma transição ridiculamente chocante da tela inicial branca para a interface do usuário preta.

Em vez disso, eu queria algo que desaparecesse na interface do usuário para evitar uma transição tão chocante. Encontrei minha resposta em algumas fontes e depois me intrometi para conseguir o que precisava. Dê uma olhada em https://gist.github.com/1026439 e https://gist.github.com/3798781 .

Uma coisa a ser observada: todos os meus ativos levam em consideração a barra de status. Isso significa que a tela inicial do meu iPhone Portrait é 20 pontos menor do que o Xcode realmente gostaria, então tenho poucos pontos de exclamação em todos os lugares. Tenho certeza de que você poderia posicionar a imagem apropriadamente se quisesse manter a área da barra de status em seu splash, mas é apenas algo para se estar ciente.

UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.window.frame];

if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
switch ( [[UIApplication sharedApplication] statusBarOrientation] )
{
case UIInterfaceOrientationLandscapeLeft:
case UIInterfaceOrientationLandscapeRight:
if ( [UIScreen mainScreen].scale == 2 ) { imageView.image = [UIImage imageNamed:@"Default-Landscape@2x~ipad.png"]; }
else { imageView.image = [UIImage imageNamed:@"Default-Landscape~ipad.png"]; }
[imageView setFrame: CGRectMake(0, 0, 1024, 748) ];
break;
case UIInterfaceOrientationPortrait:
case UIInterfaceOrientationPortraitUpsideDown:
if ( [UIScreen mainScreen].scale == 2 ) { imageView.image = [UIImage imageNamed:@"Default-Portrait@2x~ipad.png"]; }
else { imageView.image = [UIImage imageNamed:@"Default-Portrait~ipad.png"]; }
[imageView setFrame: CGRectMake(0, 0, 768, 1004) ];
break;
}
}
else
{
// we're an iPhone or iPod touch. No rotation for you.
if ( [UIScreen mainScreen].scale == 2 )
{
// are we a 3.5in? or a 4?
if ([UIScreen mainScreen].bounds.size.height == 568.0f)
{
// 4 inch iPhone 5
imageView
.image = [UIImage imageNamed:@"Default-568h@2x.png"];
[imageView setFrame: CGRectMake(0, 0, 320, 548) ];
}
else
{
imageView
.image = [UIImage imageNamed:@"Default@2x.png"];
[imageView setFrame: CGRectMake(0, 0, 320, 460) ];
}
}
else
{
imageView
.image = [UIImage imageNamed:@"Default.png"];
[imageView setFrame: CGRectMake(0, 0, 320, 460) ];
}
}
[self.window.rootViewController.view addSubview:imageView];
[self.window.rootViewController.view bringSubviewToFront:imageView];

PKWaitDelay(2,{
[UIView transitionWithView:self.window
duration
:1.00f
options
:UIViewAnimationCurveEaseInOut
animations
:^(void){
imageView
.alpha = 0.0f;
}
completion
:^(BOOL finished){
[imageView removeFromSuperview];
}];}
);
[self.window makeKeyAndVisible];

Visto que o código acima não se encaixa muito bem na coluna, coloquei uma ideia geral em https://gist.github.com/4410510 .

Você pode ter algumas perguntas – primeiro, para onde isso vai? Deve ir para o seu arquivo, pouco antes do final do seu método. AppDelegate.mdidFinishLaunchingWithOptions

A próxima pergunta que você pode ter é por que estou adicionando a imagem à minha janela rootViewController? Precisamente porque rootViewControllerestava aparecendo acima da imagem na hierarquia de visualização, o que significava que toda a animação estava ocorrendo atrás rootViewControllere fora da vista.

Finalmente, qual é essa função? Bem – é uma macro para um, definida assim:PKWaitDelay()

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,dly*100000),dispatch_get_current_queue(), ^{ block })

Portanto, o código de transição acima está realmente esperando cerca de dois segundos antes de executarmos o fade – por quê? MinhasrootViewControllere suas subvisualizações requerem um segundo ou mais para se comporem, e se iniciarmos a animação imediatamente, teremos uma transição muito chocante enquanto o dispositivo está ocupado compondo as exibições, e então obteremos o pequeno desvanecimento que resta. Portanto, decidi forçar uma pequena espera antes da transição. É possível que haja um dispositivo por aí com uma animação ruim? Eu suponho, mas realmente se resume ao que funciona para você. Independentemente disso, não vejo ir além de 3 ou 4s – a Apple indica expressamente que o aplicativo não deve de forma alguma desacelerar o processo de inicialização intencionalmente. Meu atraso de 2s não tem a intenção de retardar nada – apenas para encobrir o trabalho que está passando por baixo dos lençóis, por assim dizer. Mas se eu fosse para 4s, meu iPad ficaria inativo por 2s ou mais. Não é bom. EU’

De qualquer forma, uma vez que esmaecer a tela inicial não é terrivelmente incomum e pode ser muito útil (especialmente para diminuir o impacto de uma transição repentina), pensei em compartilhar com você.

Oh – mais uma coisa. É perfeito? Deus não. Por exemplo, se eu girar o dispositivo no meio da transição, você obtém a imagem no tamanho errado. Tenho certeza de que há uma maneira de contornar isso, mas ainda não tive tempo para descobrir isso. Que tal deixar como exercício para o leitor?