Прикосновение к UISlider предотвращает прокрутку UIScrollView
У меня есть (вертикальный) UISlider внутри UIScrollview. Я хотел бы иметь возможность изменить значение ползунка и, не поднимая пальца, прокручивать прокрутку влево или вправо.
Желаемое поведение:
Прикоснитесь внутрь вертикального UISlider, а затем перетащите его влево или вправо, чтобы прокрутить прокрутку
Фактическое поведение:
Прикоснитесь вниз по вертикали UISlider, а затем перетащите пальцем влево или вправо, что не вызывает движения в UIScrollview. Прикосновение вниз от UISlider, за которым следует перетаскивание, прокрутит прокрутку в ожидании
UIView имеет свойство, называемое exclusiveTouch, которое похоже на то, что оно может быть связано с моей проблемой. Я попробовал установить его НЕТ, без везения.
Итак, как можно настроить мои UISliders так, чтобы прокрутка под ними отвечала на касания, которые происходят внутри UISliders?
Ответы
Ответ 1
Вы пробовали подклассификацию UIScrollView
и реализацию - (BOOL)touchesShouldCancelInContentView:(UIView *)view
? Согласно документации Apple:
// called before scrolling begins if touches have already been delivered to a subview of the scroll view. if it returns NO the touches will continue to be delivered to the subview and scrolling will not occur
// not called if canCancelContentTouches is NO. default returns YES if view isn't a UIControl
Если вы просто вернете NO
, если view
- ваш UISlider
, это может сделать то, что вы хотите, если только UIScrollView
прокручивается по горизонтали. Если это не сработает, вам, скорее всего, придется выполнять пользовательскую обработку касания (например, переопределение touchesBegan:withEvent:
, touchesChanged:withEvent:
и т.д.) Для ваших UIScrollView
и UISlider
.
Ответ 2
То, что вы видите, - это предполагаемое поведение.
Каждое событие касания обрабатывается только одним элементом управления. То, что exclusiveTouch
действительно означает, чтобы другие события касания не доставлялись в другие виды.
Чтобы делать то, что вы пытаетесь сделать, вам придется самому заниматься сенсорным управлением. Передача события обоим вашим представлениям. Вы можете сделать это, выполнив все методы touchesBegan:
, touchesMoved:
и передав события обоим представлениям. Подробнее об этом подходе можно узнать в документации UIResponder. Другим подходом является обработка событий в UIGestureRecognizer в представлении прокрутки, которое ударяет по ползунку и обновляет значение ползунка с помощью y-delta. Вы можете больше узнать о распознавателях жестов и обработке событий в разделе о распознавателях жестов в Руководстве по обработке событий для iOS.
Примечание:
Перейдите в приложение "Настройки" и переключите переключатель наполовину (например, режим "Режим полета" ), а затем перетащите вниз. Ничего не случится. Остальная часть ОС ведет себя одинаково. Вы уверены, что это взаимодействие, которое вы действительно хотите сделать? Приложения, которые ведут себя по-разному, часто кажутся странными и незнакомыми.
Ответ 3
Ваш вопрос немного смутил меня. Вы говорите вертикальный слайдер - но перетаскиваете влево и вправо?
Если вы хотите прокрутить список прокрутки при перетаскивании UISlider, правильный способ сделать это -
[mySlider addTarget:self action:@selector(sliderMoved:) forControlEvents:UIControlEventValueChanged];
и
- (void) sliderMoved:(UISlider*) slider {
myScrollView.contentOffset.x = slider.value * (myScrollView.contentSize.width - myScrollView.bounds.size.width);
}
Надеюсь, это то, что вы хотите.
Ответ 4
Вам нужно установить задержекContentTouches как НЕТ и предотвратить прокрутку объектов UISlider, Проверить код ниже.
mySlider.delaysContentTouches = NO;
- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
if ([view isKindOfClass:[UISlider class]])
{
UITouch *touchEvent = [[event allTouches] anyObject];
CGPoint locationEvent = [touchEvent locationInView:view];
CGRect thumbRect;
UISlider *mySlide = (UISlider*) view;
CGRect trackRect = [mySlide trackRectForBounds:mySlide.bounds];
thumbRect = [mySlide thumbRectForBounds:mySlide.bounds trackRect:trackRect value:mySlide.value];
if (CGRectContainsPoint(thumbRect, locationEvent))
return YES;
}
return NO;
}
Ответ 5
Я думаю, что вы можете получить некоторую ссылку из этот пример в этом примере показано, что как отменить любое касание или любые распознаватели жестов и применить их к другим представлениям.
Пусть это приведет вас к решению вашей проблемы, и если это просто сообщит мне об этом
Happy Codding:)