Pergunta

Então, eu tenho este aplicativo para iPhone com uma configuração aninhada como esta: [rootViewController]-> [uitabbarController]-> [uinavigationController]-> [SubviewControllers]. Tudo é construído programaticamente, não no construtor de interface.

Estou simplesmente tentando suportar todas as orientações do dispositivo. Todas as minhas máscaras automobilizando são configuradas e tudo gira e se expande/contrata conforme necessário. Tudo, exceto a barra de navegação e barra de ferramentas do NavigationController. (Normalmente, essas visualizações resistem automaticamente, dependendo da orientação. IE na paisagem, a barra de marinha e a barra de ferramentas devem redimensionar automaticamente para cerca de 32px e 44px no modo Portrai.) O que é peculiar é que a subvisão do controlador de navegação está redimensionando, mas A barra naval e a barra de ferramentas reais não são. Em outras palavras, o conteúdo se estende/encolhe cerca de 12 px ou mais, em qualquer direção, como se a barra de marinho e a barra de ferramentas redimensionassem. Parece ser as máscaras automobilizando o trabalho deles.

Portanto, para tentar resolver essa situação, criei uma categoria para o UinAvigationController que responde a 'WillrotateTointerfaceRientation: Duração:' Para acionar o seletor 'sizetofit'. (Essa técnica veio de outro post sobre o Stack Overflow, com um problema semelhante.) Descobri, em minha pesquisa, que apenas o controlador de exibição mais externo recebe essa mensagem, no entanto, então eu tenho meu controlador de vista raiz chamando isso no controlador da guia, que Por sua vez, o chama no controlador nav, etc. Isso cuidou desse problema, e agora meus controladores de vista aninhados estão sendo notificados quando a visão externa é girada. Usando a técnica sizetofit, a barra de navegação e a barra de ferramentas estão redimensionando por conta própria. No entanto, isso ainda deixa a questão de reposicionar a barra de ferramentas, a fim de compensar o deslocamento da mudança de tamanho. (Desde que nossa visualização coordena no iPhone inicia no canto superior esquerdo.)

O que torna isso complicado de fazer dentro do método Willrotate é que não temos como saber quais serão as novas dimensões da visão limitada, nem sabemos qual é a nossa orientação atual. (A menos que você tenha orientação de dispositivo, não astificações ativadas, o que não tenho.) Tudo o que precisamos trabalhar é com o que será a nova orientação e quais são os valores de quadros atuais da nossa barra de ferramentas. Eu poderia codificar isso e calcular ajustes de quadros da maneira antiga usando um pedaço de papel de arranhão, mas eu realmente quero manter os recursos de dimensionamento de visão dinâmica sem fazer suposições sobre as dimensões da tela do dispositivo.

Portanto, usando o código a seguir, consegui remediar isso simplesmente 'batendo' na barra de ferramentas por 12px em relação ao tamanho que acabou de se tornar. Para impedir que ele se abate demais quando o usuário vira o dispositivo, uso a altura da estrutura da barra de ferramentas atual para derivar a orientação atual. (Isso significa que ainda estou assumindo uma suposição sobre a barra de ferramentas antes e depois dos tamanhos, mas me sinto melhor com isso, pois posso influenciar isso até certo ponto, em vez de tentar redimensionar programaticamente a tela física do dispositivo.)

@implementation UINavigationController (BLUINavigationControllerAutoRotate)

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
    return TRUE;
}

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];

    // Resize the navBar
    [[self navigationBar] performSelector:@selector(sizeToFit)
                               withObject:nil
                               afterDelay:(0.5f * duration)];

    // Read our current frame size
    CGRect toolbarFrame = self.toolbar.frame;

    // Prevent over adjusting when flipping the device
    if ((toolbarFrame.size.height < 38
         && (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft
             || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
        || (toolbarFrame.size.height > 38
            && (toInterfaceOrientation == UIInterfaceOrientationPortrait
                || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)))
    {
        // We are already resized and repositioned.
        return;
    }

    // Calculate and apply the toolbar offset
    const NSInteger delta = 12;     // the difference in size between 44 and 32 px.
    toolbarFrame.origin.y += ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
                              || (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)) ? (delta) : (-delta);
    self.toolbar.frame = toolbarFrame;

    // Resize the toolbar
    [[self toolbar] performSelector:@selector(sizeToFit)
                         withObject:nil
                         afterDelay:(0.5f * duration)];

}

@end

Então, agora eu me comportou adequadamente na barra de navegação e na barra de ferramentas. O usuário final nunca saberá que eu tinha que implementar todo esse trabalho extra para reativar o que parece ser um comportamento padrão. Então, minha pergunta é: por que tenho que fazer tudo isso? Existe uma abordagem melhor que eu deveria conhecer, ou algo que eu simplesmente não estou fazendo em outro lugar? (ou seja, [NavigationController setautomaticaticamente resmunção do Baronrotate: True]; ou algo assim?) Como eu disse, isso parece que deveria ser pré-conectado, então para mim ter que finalizar com mensagens de encaminhamento e gatilhos forçados parecem um hack exagerado em vez da solução adequada.

Obrigado!

Foi útil?

Solução

Você está passando a mensagem WillrotateTointerFaceRientation para o controlador de exibição da guia do seu controlador de exibição raiz - por que não transmitir todas as outras mensagens de rotação e ver se isso ajuda? ou seja

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation  {
    [super didRotateFromInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didRotateFromInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
}

- (void)didAnimateFirstHalfOfRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
    [super didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
    [tabBarController didAnimateFirstHalfOfRotationToInterfaceOrientation:toInterfaceOrientation];
}

- (void)willAnimateSecondHalfOfRotationFromInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
    [super willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
    [tabBarController willAnimateSecondHalfOfRotationFromInterfaceOrientation:toInterfaceOrientation duration:duration];
}

Eu estaria interessado em ver o que acontece se você passar tudo isso para o controlador da barra de guias - seu problema parece algo que deve acontecer automaticamente, em vez de ser todo o trabalho extra que você fez!

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top