Problemy z wyglądem UIBarButtonItem w iOS 7, czy może to być błąd Apple?
Jakiś czas temu widziałem artykuł, który jest tutaj:
Dostosowywanie interfejsu użytkownika w systemie iOS 6
Pokazuje dostosowanie do systemu iOS 6. Od czasu, gdy napisałem aplikacje, które używają tej techniki, jest całkiem proste, nie ma tam żadnej magii.
Muszę jednak zaktualizować jedną z moich aplikacji, aw systemie iOS 7 nie działa poprawnie. Wydaje się, że dostosowywanie UIBarButtonItems nie działa przy pierwszym przedstawieniu widoku. Jeśli odrzucę widok, a następnie przedstawię go, wszystko działa dobrze. Widoczne jest tutaj:
Wyświetlany jest pierwszy widok:
Drugi raz:
Widziałem ten problem w swoim przykładzie, moim kodzie i aplikacji testowej, którą napisałem. Kod jest następujący:
// 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];
Jak widać, nie ma prawdziwej magii, całkiem standardowej, ale nie mogę znaleźć żadnego powodu ani wyjaśnienia, dlaczego to nie działa w iOS 7. Kod zostaje wykonany w- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
.
Mam nadzieję, że ktoś to widział i może zaoferować rozwiązanie. Dzięki za pomoc!
** Uwaga: zaproponowano, że nie jest to błąd jabłkowy, ale z założenia. Nie mówię, że JEST to kwestia jabłek, może bardziej prawdopodobne, że jest moja, ale jeśli uruchomisz jedną z próbek lub skopiujesz i wkleisz poniższy kod, jest oczywiste, że za pierwszym razem nie działa poprawnie, a później. To doprowadziłoby mnie do przekonania, że wywołania api są prawidłowe, ale albo mają błąd, albo brakuje czegoś, co trzeba zrobić.
**** AKTUALIZACJA 4: **
Zmieniłem kod w metodzie początkowej MyAppDelegate w moim przykładzie na następujący, w oparciu o sugestię FruityGeek, ale nadal nie mam szczęścia:
- (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;
}
**** AKTUALIZACJA 3: **
Dodano przykładowy link do projektu przykładowego. Jest to dodatek do już opublikowanego linku powyżej, który jest prostą aplikacją, która również pokazuje problem. Oba można zbudować i uruchomić w symulatorze z iOS 6 i iOS 7. W przypadku iOS 6 wszystko działa zgodnie z oczekiwaniami. W systemie iOS 7, jeśli klikniesz komórkę tabeli i wyświetlisz następny widok, niestandardowy przycisk Wstecz nie zostanie wyświetlony, jeśli wrócisz i ponownie go wyświetlisz, przycisk jest tam.
Oszukiwałem to od wielu dni, więc mam nadzieję, że ktoś inny to zobaczy i powie mi, czego mi brakuje.
https://www.dropbox.com/s/oi1bh3emvtbmms0/NavigationBarDemo.zip
To może być głupie, ale czy może mieć to związek z moimi obrazami? Spróbuję próbki z różnymi obrazami i opublikuję aktualizację.
Wypróbowane z różnymi obrazami i to nie robi różnicy, użyłem również obrazów z powyższej próbki. To był długi strzał, ale ponieważ nikt nie wydaje się mieć lepszego pomysłu, warto było spróbować.**** AKTUALIZACJA 2: **
Próbowałem tego w innej aplikacji testowej i przeniosłem kod do polecenia inicjującego delegata aplikacji i nadal nie działa. Mam to opublikowane tutaj, a także oryginalną stronę autorów linku na górze. Plus inne forum, ale nikt nie wydaje się mieć rozwiązania.
Zastanawiam się, czy to może być błąd Apple?
**** AKTUALIZACJA 1: **
Przeniesiony kod zdidFinishLaunchingWithOptions
dowillFinishLaunchingWithOptions
iinit
i nadal nie wydaje się działać.
***** 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];
}