Problema de aparência UIBarButtonItem no iOS 7, isso poderia ser um bug da Apple?
Eu vi um artigo um tempo atrás, que está aqui:
Personalização da interface do usuário no iOS 6
Ele mostra a personalização para o iOS 6. Desde o artigo que escrevi Apps que usam a técnica, é bastante simples, não há mágica lá.
No entanto, preciso atualizar um dos meus aplicativos e, no iOS 7, ele não funciona corretamente. Parece que a personalização de UIBarButtonItems não funciona na primeira vez que a exibição é apresentada. Se eu dispensar o ponto de vista e, em seguida, apresentá-lo agin tudo funciona bem. O que é visto é mostrado aqui:
A primeira visão é apresentada:
Segundo tempo:
Eu vi esse problema em seu exemplo, meu código e um aplicativo de teste que eu escrevi. O código é o seguinte:
// Customizing the Back Bar Buttons
UIImage * btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
UIImage * btBack_24 = [[UIImage imageNamed:@"btBack_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
Como você pode ver, não há mágica real, padrão, mas não consigo encontrar nenhuma razão ou explicação para isso não funcionar no iOS 7. O código é executado em- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
.
Espero que alguém tenha visto isso e possa oferecer uma solução. Obrigado por qualquer ajuda!
** Nota: foi proposto que este não é um bug da apple, mas pelo design. Eu não estou dizendo que é um problema de maçã, poderia mais provavelmente ser meu, mas se você executar qualquer um dos exemplos ou copiar e colar o código abaixo, é aparente que a primeira vez que não funciona corretamente e vezes subseqüentes que ele faz. Isso me levaria a acreditar que as chamadas da API são válidas, mas elas têm um bug ou estou perdendo algo que precisa ser feito.
**** ATUALIZAÇÃO 4: **
Eu mudei o código no método init MyAppDelegate no meu exemplo para o seguinte com base na sugestão de FruityGeek, mas ainda sem sorte:
- (instancetype)init
{
self = [super init];
if (self)
{
//Other UIAppearance proxy calls go here
[[UIBarButtonItem appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
//[UIColor colorWithRed:220.0/255.0 green:104.0/255.0 blue:1.0/255.0 alpha:1.0],
[UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
UITextAttributeTextColor,
//[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0],
[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(0.5, 0.5)],
UITextAttributeTextShadowOffset,
[UIFont systemFontOfSize:12.0],
UITextAttributeFont,
nil]
forState:UIControlStateNormal];
// Customizing the Back Bar Buttons
//ios6 uses whole button background image
UIImage * btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
UIImage * btBack_24 = [[UIImage imageNamed:@"btBack_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
if ([[UIDevice currentDevice].systemVersion integerValue] >= 7)
{
//ios7 needs additional chevron replacement image
UIImage * chevronReplacement = chevronReplacement = [btBack_30 imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
UIImage * chevronTransitionMaskReplacement = chevronTransitionMaskReplacement = [btBack_30 imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[[UINavigationBar appearance] setBackIndicatorImage:chevronReplacement];
[[UINavigationBar appearance] setBackIndicatorTransitionMaskImage:chevronTransitionMaskReplacement];
}
}
return self;
}
**** ATUALIZAÇÃO 3: **
Eu adicionei um link de dropbox para um projeto de amostra. Isto é, além do link já publicado acima, que é um aplicativo simples que também mostra o problema. Ambos podem ser criados e executados no simulador com iOS 6 e iOS 7. No caso do iOS 6, tudo funciona conforme o esperado. No iOS 7, se você clicar na célula da tabela e apresentar a próxima exibição, o botão Voltar não será mostrado. Se você voltar e apresentá-lo novamente, o botão estará lá.
Eu tenho brincado com isso por dias, então eu espero que alguém veja e possa me dizer o que eu estou perdendo.
https://www.dropbox.com/s/oi1bh3emvtbmms0/NavigationBarDemo.zip
Isso pode ser bobo, mas poderia ter a ver com minhas imagens? Vou tentar a amostra com imagens diferentes e postar uma atualização.
Tentei com imagens diferentes e isso não faz diferença, também usei imagens da amostra postada acima. Foi um tiro longo, mas desde que ninguém parece ter uma idéia melhor, no entanto, valeu a pena tentar.**** ATUALIZAÇÃO 2: **
Eu tentei isso em outro aplicativo de teste e movi o código para o initeded do delegado do aplicativo e ele ainda não funciona. Eu tenho isso postado aqui, bem como o site dos autores originais do link no topo. Mais outro fórum, mas ninguém parece ter uma solução.
Eu estou querendo saber se isso poderia ser um bug da Apple?
**** ATUALIZAÇÃO 1: **
Código movido dedidFinishLaunchingWithOptions
parawillFinishLaunchingWithOptions
einit
e ainda não parece funcionar.
***** INIT METHOD FROM AppDelegate.m
- (id)init
{
// Create resizable images
UIImage *gradientImage44 = [[UIImage imageNamed:@"navBar_44"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
UIImage *gradientImage32 = [[UIImage imageNamed:@"navBar_32"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
// Set the background image for *all* UINavigationBars
[[UINavigationBar appearance] setBackgroundImage:gradientImage44 forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setBackgroundImage:gradientImage32 forBarMetrics:UIBarMetricsLandscapePhone];
// Customize the title text for *all* UINavigationBars
[[UINavigationBar appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
UITextAttributeTextColor,
[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(1, 1)],
UITextAttributeTextShadowOffset,
[UIFont boldSystemFontOfSize:18.0],
UITextAttributeFont,
nil]];
// Customizing the NavBar Buttons
UIImage * button30 = [[UIImage imageNamed:@"btButton_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
UIImage * button24 = [[UIImage imageNamed:@"btButton_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UIBarButtonItem appearance] setBackgroundImage:button30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundImage:button24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
[[UIBarButtonItem appearance] setTintColor:[UIColor whiteColor]];
[[UIBarButtonItem appearance] setTitleTextAttributes:
[NSDictionary dictionaryWithObjectsAndKeys:
//[UIColor colorWithRed:220.0/255.0 green:104.0/255.0 blue:1.0/255.0 alpha:1.0],
[UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0],
UITextAttributeTextColor,
//[UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0],
[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(0.5, 0.5)],
UITextAttributeTextShadowOffset,
[UIFont systemFontOfSize:12.0],
UITextAttributeFont,
nil]
forState:UIControlStateNormal];
// Customizing the Back Bar Buttons
UIImage * btBack_30 = [[UIImage imageNamed:@"btBack_30"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
UIImage * btBack_24 = [[UIImage imageNamed:@"btBack_24"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_30 forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:btBack_24 forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];
return [super init];
}