2013-09-11 27 views
25

Mam UISegmentedControl w mojej aplikacji. Od wersji GM iOS7 obrazy, których używam, nie wyświetlają się po uruchomieniu na urządzeniach z iOS7. Ktoś jeszcze ma ten problem?UISegmentedControl setImage: Bug w iOS7

Oto, jak to wygląda w iOS6.1 i wcześniejszym iOS6-ScreenShot.

i oto jak to wygląda w iOS7 iOS7-ScreenShot.

Oto kod:

self.theSegmentedControl.frame = CGRectMake(self.theSegmentedControl.frame.origin.x, self.theSegmentedControl.frame.origin.y, 320, 35); 
[self.theSegmentedControl setBackgroundImage:[UIImage imageNamed:@"img_toggleInactive"] forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 
[self.theSegmentedControl setImage:[UIImage imageNamed:@"btn_onceActive"] forSegmentAtIndex:0]; 
[self.theSegmentedControl setImage:[UIImage imageNamed:@"btn_recurringInactive"] forSegmentAtIndex:1]; 
[self.theSegmentedControl setImage:[UIImage imageNamed:@"btn_scheduledInactive"] forSegmentAtIndex:2]; 
[self.theSegmentedControl setDividerImage:[UIImage imageNamed:@"separator"] forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 

Czy ktoś znalazł obejście tego?

+0

to nie jest ale, to funkcja! Apple dokonał bardzo dziwnego wyboru, aby całkowicie odmalować obrazy w swoich segmentowanych kontrolkach. Ja w mojej aplikacji użyłem seg, aby wybrać kolor, teraz moje kolory są niebieskie! – Martin

Odpowiedz

61

Woohoo! Oto obejście:

//Add clear color to mask any bits of a selection state that the object might show around the images 
self.theSegmentedControl.tintColor = [UIColor clearColor]; 

UIImage *onceActive; 
UIImage *recurringActive; 
UIImage *scheduledActive; 
UIImage *separator; 

//Setting imageWithRenderingMode: to imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal for iOS7 is key 
if ([UIImage instancesRespondToSelector:@selector(imageWithRenderingMode:)]) { 
    onceActive = [[UIImage imageNamed:@"btn_onceActive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 
    recurringActive = [[UIImage imageNamed:@"btn_recurringInactive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 
    scheduledActive = [[UIImage imageNamed:@"btn_scheduledInactive"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 
    separator = [[UIImage imageNamed:@"separator"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 

} 
else { 
    onceActive = [UIImage imageNamed:@"btn_onceActive"]; 
    recurringActive = [UIImage imageNamed:@"btn_recurringInactive"]; 
    scheduledActive = [UIImage imageNamed:@"btn_scheduledInactive"]; 
    separator = [UIImage imageNamed:@"separator"]; 
} 


[self.theSegmentedControl setImage:onceActive forSegmentAtIndex:0]; 
[self.theSegmentedControl setImage:recurringActive forSegmentAtIndex:1]; 
[self.theSegmentedControl setImage:scheduledActive forSegmentAtIndex:2]; 
[self.theSegmentedControl setDividerImage:separator forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 
+2

To nie jest "obejście", które zostało jednoznacznie nazwane w jednym z wideoklipów WWDC, jako konieczną czynność w tym przypadku. – Petesh

+25

Kod bez nowej metody działał w iOS6.1 i niżej i zatrzymał się w 7. Nie ma wskazania w dokumentach lub konsoli, aby zrobić coś inaczej. Ciężar odpowiedzialności nie spoczywa na mnie, aby oglądać wszystkie filmy WWDC. Zamierzam iść dalej i nazwać to błędem, dziękuję. – kevmalek

+2

Czy przekompilowałeś swój kod za pomocą nowego zestawu SDK? Dokumenty * wyraźnie * wskazują, że: Ikony segmentów Możesz użyć obrazu zamiast tekstu tytułowego dla swoich segmentów. Zauważ, że obraz segmentu zostanie automatycznie renderowany jako obraz szablonu w ramach kontroli podzielonej na segmenty, chyba że wyraźnie ustawisz tryb renderowania na UIImageRenderingModeAlwaysOriginal. Aby uzyskać więcej informacji, zobacz Obrazy szablonów (nie łączę się z tym, ponieważ link jest nadal w wersji wstępnej). – Petesh

17

UPDATE dla Xcode 6/iOS 8

Teraz można to zrobić w konstruktorze Interface

Wystarczy dodać plik obrazu w katalogu aktywów i ustawić jej „render jako”oryginalnego obrazu zamiast domyślnie

Xcode 5

Nowa kontrola UISegmented używa koloru tinty do odbarwienia obrazów przy użyciu trybu szablonu. Będziesz musiał renderować te obrazy jako oryginalne, a nie szablony.

Jak sugerowano w komentarzach to zrobić:

UIImage* onceActive = [UIImage imageNamed:@"btn_onceActive"]; 
if (IOS_7_MACRO) 
    onceActive = [onceActive imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 
[self.theSegmentedControl setImage:onceActive forSegmentAtIndex:0]; 
+0

Jak można przekazać użytkownikowi tryb renderowania AlwaysOriginal z XIB/Interface Builder? – user282172

+2

Nie widziałem tej opcji w IB przynajmniej dla UISegmentedControl :( –

+1

Od Xcode 6 można ustawić tryb renderowania we właściwościach katalogu Assets dla każdego zasobu: D –

2

To może być przydatne, aby utworzyć kategorię:

@interface UISegmentedControl (UISegmentedControlAdditions) 
    -(void)setImageRenderingMode:(UIImageRenderingMode)renderingMode; 
@end  

@implementation UISegmentedControl (UISegmentedControlAdditions) 
    -(void)setImageRenderingMode:(UIImageRenderingMode)renderingMode { 
     for (int index=0; index < [self numberOfSegments]; index++) { 
      UIImage * image = [self imageForSegmentAtIndex:index]; 
      [self setImage:[image imageWithRenderingMode:renderingMode] forSegmentAtIndex:index]; 
     } 
    } 

... i po prostu zadzwonić

if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) 
    [colorSegmentedControl setImageRenderingMode:UIImageRenderingModeAlwaysOriginal]; 
+0

'imageWithRenderingMode:' jest już obecny w 'UIImage' .Dlaczego więc utworzyć kategorię? Dostępna tylko w iOS 7.0 lub później –

+0

Tak,' imageWithRenderingMode: ' jest również metodą "UIImage": ten przykład go używa.) Po co tworzyć kategorię? Ponieważ jest mniej dokładny i użyteczny niż ręczna konfiguracja kontrolek. Ale oczywiście jest jeszcze lepiej, tworząc własną klasę "UISegmentedControl". – Martin

7

Użyj tego Kod do ustawienia Obraz kontroli segmentów w systemie iOS 7 z kodem x 5.0

if ([UIImage instancesRespondToSelector:@selector(imageWithRenderingMode:)]) { 

    [segmentControl setImage:[[UIImage imageNamed:@"image.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forSegmentAtIndex:0]; 

} 
else { 
    [segmentControl setImage:[UIImage imageNamed:@"image.png"] forSegmentAtIndex:0]; 
}