Подтвердить что ты не робот

UISegmentedControl в образе делителя iOS 7 неверно во время анимации

У меня есть пользовательский UISegmentedControl. В iOS 6 и ниже он работает нормально. В 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, что может привести к неправильному отображению разделителя? Благодаря?

4b9b3361

Ответ 1

Я решил это так, как описано в 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, но по крайней мере это будет держать ваш код немного чистым.

Ответ 2

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

Я смог исправить эту проблему, удалив анимацию по умолчанию для backgroundImage и заголовков (UILabel), вызвав removeAllAnimations на уровне сегмента, а также вызвав removeAllAnimations на UILabel, вложенном внутри каждого сегмента. Я поместил этот код в метод IBAction, который вызывается при запуске события с переменным значением 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]

Ответ 3

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

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    CATransaction.setDisableActions(true)
    super.touchesEnded(touches, withEvent: event)
}

Ответ 4

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

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

Ответ 5

Чтобы добавить немного подробней к ответу Wyatt, происходит то, что изображение "делитель" и новое "выбранное" изображение мгновенно меняются на touchUp, но ранее выбранный переход сегмента с "выбранного" изображения на "невыделенное" изображение выполняется с помощью анимированного кроссфейда.

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

Ответ 6

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