2013-09-19 3 views
17

У меня есть пользовательский UISegmentedControl. В iOS 6 и ниже он работает нормально. Под iOS 7 .. он выглядит нормально, пока я не нажму кнопку управления, и в это время изображение разделителя выглядит странно в течение секунды секунды.UISegmentedControl in iOS 7 изображение разделителя неправильное во время анимации

Вот мой код:

UIImage *segmentSelected = [[UIImage imageNamed:@"segcontrol_sel.png"] 
           resizableImageWithCapInsets:UIEdgeInsetsMake(6, 6, 6, 6)]; 
    UIImage *segmentUnselected = [[UIImage imageNamed:@"segcontrol_unsel.png"] 
            resizableImageWithCapInsets:UIEdgeInsetsMake(6, 6, 6, 6)]; 
    UIImage *segmentSelectedUnselected = 
    [UIImage imageNamed:@"segcontrol_sel_uns.png"]; 
    UIImage *segUnselectedSelected = 
    [UIImage imageNamed:@"segcontrol_uns_sel.png"]; 

    [[UISegmentedControl appearance] setBackgroundImage:segmentUnselected 
               forState:UIControlStateNormal barMetrics:UIBarMetricsDefault]; 
    [[UISegmentedControl appearance] setBackgroundImage:segmentSelected 
               forState:UIControlStateSelected barMetrics:UIBarMetricsDefault]; 
    [[UISegmentedControl appearance] setBackgroundImage:segmentUnselected 
               forState:UIControlStateHighlighted barMetrics:UIBarMetricsDefault]; 

    [[UISegmentedControl appearance] setDividerImage:segUnselectedSelected 
           forLeftSegmentState:UIControlStateNormal // | UIControlStateHighlighted 
            rightSegmentState:UIControlStateSelected 
              barMetrics:UIBarMetricsDefault]; 
    [[UISegmentedControl appearance] setDividerImage:segUnselectedSelected 
           forLeftSegmentState:UIControlStateHighlighted 
            rightSegmentState:UIControlStateSelected 
              barMetrics:UIBarMetricsDefault]; 
    [[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected 
           forLeftSegmentState:UIControlStateSelected 
            rightSegmentState:UIControlStateNormal //| UIControlStateHighlighted) 
              barMetrics:UIBarMetricsDefault]; 
    [[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected 
           forLeftSegmentState:UIControlStateSelected 
            rightSegmentState:UIControlStateHighlighted 
              barMetrics:UIBarMetricsDefault]; 

    UIFont *font = [UIFont systemFontOfSize:16.0f]; 
    UIColor *textColor = [UIColor darkGrayColor]; 
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys: 
           font, @"NSFontAttributeName", 
           textColor, @"NSForegroundColorAttributeName", 
           nil]; 

    [[UISegmentedControl appearance] setTitleTextAttributes:attributes 
                forState:UIControlStateNormal]; 

Любые идеи, что происходит, когда я нажимаю UISegmentedControl, что может вызвать делитель, который будет отображаться неправильно? Спасибо?

+1

Понятия не имею, что здесь происходит, но у меня такая же проблема. Мне кажется, что яблоко просто переворачивает центральное изображение (изображение разделителя) быстрее, чем они перевертывают внешние части (фоновое изображение). Если бы вам удалось найти исправление, можете ли вы сообщить мне об этом? – simonthumper

+0

Вы нашли исправление? У меня такая же проблема. – Imran

ответ

6

Я решил это таким образом, подобно тому, что user2128193 описывает, но вместо добавления мишени для события значения изменилось, я подклассы UISegmentedControl и добавили эти два метода:

- (void)sendActionsForControlEvents:(UIControlEvents)controlEvents 
{ 
    [super sendActionsForControlEvents:controlEvents]; 

    if (controlEvents & UIControlEventValueChanged) { 
     [self removeAnimationsRecursivelyForView:self]; 
    } 
} 

- (void)removeAnimationsRecursivelyForView:(UIView *)view 
{ 
    [view.layer removeAllAnimations]; 

    for (UIView *subview in [view subviews]) { 
     [self removeAnimationsRecursivelyForView:subview]; 
    } 
} 

Очевидно, что это все еще не является идеальное решение, поскольку оно опирается на внутренности UISegmentedControl, но, по крайней мере, это будет держать ваш код немного чище.

+0

По какой-то причине это работает, когда сегмент используется быстро, но не работает * после того, как сегмент был нажат некоторое время. –

1

У меня возникла аналогичная проблема, и выяснилось, что происходят две вещи. Один из них вы уже рассмотрели (настройка изображений для выделенных/выделенных комбо). В другом случае UISegmentedControl выделяет цвет, когда вы выбираете новый сегмент, например, UITableViewCells, когда вы их выбираете. И хотя я настроил все искусство и текст, он все еще исчезает до темного цвета (мой текст даже инвертирует), а затем он возвращается. Во время этого замирания края моих разделителей легко видны.

Мне пришлось включить Медленную анимацию в Симуляторе, чтобы увидеть это более четко. К сожалению, мне не удалось найти способ отключить эти анимации по умолчанию.

+0

Спасибо Wyatt! Я все еще не мог найти правильный способ сделать это. Однако ваш ответ проливает свет. Похоже, установка разделителя для состояния SelectedSelected помогает немного, но все еще недостаточно. – Fervus

4

TL; DR Просто удалите все анимации в каждом сегменте. Смотрите ниже код

Я был в состоянии решить эту проблему путем удаления анимации по умолчанию для BackgroundImage и названий (UILabel), вызвав removeAllAnimations на слое сегмента, а также вызов removeAllAnimations на UILabel вложенный внутри каждый сегмент. Я поместил этот код в метод IBAction, который вызывается, когда запускается событие ValueShanged UISegmentedControl.

- (IBAction)tabSelected:(id)sender 
{ 
    UISegmentedControl *segmentedControl = (UISegmentedControl *)sender; 

    for (UIView *segment in [segmentedControl subviews]) { 
     [segment.layer removeAllAnimations]; 

     for (UIView *view in [segment subviews]) { 
      if ([view isKindOfClass:[UILabel class]]) { 
       [view.layer removeAllAnimations]; 
      } 
     } 
    } 
} 

Я не проверял это на содержание, которое является UIImage, но я не вижу причин, почему это не будет работать до тех пор, как вы измените эту строку:

[view isKindOfClass:[UILabel class] 

, чтобы соответствовать для UIImage класс так:

[view isKindOfClass:[UIImage class] 
+0

Я добавил это в: [_segmentedControl addTarget: self action: @selector (onClick) forControlEvents: UIControlEventValueChanged]; для исправления нежелательного замирания в проблеме анимации. Благодаря! – Imran

+0

Я также могу подтвердить эти работы для UIImage. Я поместил код в IBAction для «Value Changed». Благодаря! – arinmorf

1

чтобы добавить немного больше деталей к ответу Вьятты, что происходит в том, что «разделитель» изображения и новое «выбраны» изображение меняются мгновенно по TouchUp, но ранее выбранный segme Переход nt с «выбранного» изображения на «невыбранный» образ выполняется с помощью анимированного кроссфейда.

Если у вас широкое изображение «разделителя» с высоким контрастом между изображением «разделитель» и «выбранным» изображением, это приводит к раздражающей вспышке.

0

Попробуйте установить свойство tintcolor управления сегментом. У меня была эта проблема. Я установил цвет оттенка на цвет выбора и не было установлено никаких изображений для разделителя. Так как это IOS 7, вы можете сделать это для IOS 7 и сохранить код кода делителя для IOS 6. Чтобы все было ясно, я говорю о свойствах экземпляра экземпляра tintcolor UISegmentControl.

2

Я решил это переопределение touchesEnded в подклассе и отключение анимации для CATransaction

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) { 
    CATransaction.setDisableActions(true) 
    super.touchesEnded(touches, withEvent: event) 
} 
Смежные вопросы