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