2013-09-11 2 views
25

У меня есть UISegmentedControl в моем приложении. Начиная с iOS7 GM, изображения, которые я использую, не отображаются при запуске на устройствах iOS7. У кого-нибудь еще есть эта проблема?UISegmentedControl setImage: ошибка в iOS7

Вот как он выглядит в iOS6.1 и более ранних версиях iOS6-ScreenShot.

и вот что он выглядит в iOS7 iOS7-ScreenShot.

Вот код:

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]; 

Кто нашел обходной путь к этому?

+0

это не но, это особенность! Apple сделала очень странный выбор, чтобы полностью окрасить изображения в его сегментированные элементы управления. Я мое приложение, я использовал сег, чтобы выбрать цвет, теперь мои цвета все голубые! – Martin

ответ

61

Woohoo! Вот обходной путь:

//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

Это не «обходной путь», он был явно вызван в одном из видео WWDC в качестве необходимой вещи в этом случае. – Petesh

+25

Код без нового метода работал в iOS6.1 и ниже и остановился в 7. Нет указаний в документах или консоли, чтобы делать что-либо по-другому. Ответственность не лежит на мне, чтобы смотреть все видео WWDC. Я собираюсь пойти и назвать это ошибкой, спасибо. – kevmalek

+2

Вы перекомпилировали свой код с помощью нового SDK? Документы * четко * указывают, что: Значки сегментов Вы можете использовать изображение вместо текста заголовка для своих сегментов. Обратите внимание, что сегментное изображение будет автоматически отображаться как образ шаблона в сегментированном элементе управления, если вы явно не установите его режим рендеринга в UIImageRenderingModeAlwaysOriginal. Дополнительную информацию см. В разделе «Изображения шаблонов» (я не привязываюсь к нему, поскольку ссылка все еще находится в предварительном выпуске) – Petesh

17

UPDATE для Xcode 6/IOS 8

Теперь вы можете сделать это в строителе Interface

Просто добавьте файл изображения в каталоге активов и установить его «визуализацию как»исходное изображение, а не по умолчанию

Xcode 5

Новый элемент управления UISegmented использует цвет оттенка, чтобы затемнить изображения в режиме шаблона. Вам нужно будет сделать эти изображения оригинальными, а не шаблонами.

Как было предложено в комментариях это сделать:

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

Как вы сообщаете пользователю режим AlwaysOriginal Rendering из XIB/Interface Builder? – user282172

+2

Я не видел эту опцию в IB хотя бы для UISegmentedControl :( –

+1

Начиная с Xcode 6 вы можете установить режим рендеринга в свойствах свойств активов для каждого актива: D –

2

Это может быть полезно для создания категории:

@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]; 
     } 
    } 

... и просто позвонить

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

'imageWithRenderingMode:' уже присутствует в 'UIImage'. Тогда зачем создавать категорию? Доступно только в iOS 7.0 и далее. –

+0

Да,' imageWithRenderingMode: ' также является методом 'UIImage': этот пример использует его. Зачем создавать категорию? Потому что он менее подробный и полезный, чем настройка вручную ваших элементов управления. Но, конечно, это даже лучше, создав собственный класс 'UISegmentedControl'. – Martin

7

Используйте этот Код для установки Image on Segment Control в iOS 7 с xCode 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]; 
} 
Смежные вопросы