What I want to get is a UISlider
which lets the user not only slide when he starts on its thumbRect
, but also when he taps elsewhere. When the user
I completed @DWilliames solution for a UISlider
subclass containing minimum
and maximumValueImages
.
Additionally I implemented a functionality for user touches in the areas outside the trackArea
(means either the area around the minimum
or the maximumValueImage
). Touching these areas moves the slider/changes the value in intervals.
- (void) tapAndSlide: (UILongPressGestureRecognizer*) gesture {
CGPoint touchPoint = [gesture locationInView: self];
CGRect trackRect = [self trackRectForBounds: self.bounds];
CGFloat thumbWidth = [self thumbRectForBounds: self.bounds trackRect: trackRect value: self.value].size.width;
CGRect trackArea = CGRectMake(trackRect.origin.x, 0, trackRect.size.width, self.bounds.size.height);
CGFloat value;
if (CGRectContainsPoint(trackArea, touchPoint)) {
if (touchPoint.x <= trackArea.origin.x + thumbWidth/2.0) {
value = self.minimumValue;
}
else if (touchPoint.x >= trackArea.origin.x + trackArea.size.width - thumbWidth/2.0) {
value = self.maximumValue;
}
else {
CGFloat percentage = (touchPoint.x - trackArea.origin.x - thumbWidth/2.0)/(trackArea.size.width - thumbWidth);
CGFloat delta = percentage*(self.maximumValue - self.minimumValue);
value = self.minimumValue + delta;
}
if (value != self.value) {
if (gesture.state == UIGestureRecognizerStateBegan) {
[UIView animateWithDuration: 0.2 delay: 0 options: UIViewAnimationOptionCurveEaseInOut animations: ^{
[self setValue: value animated: YES];
} completion: ^(BOOL finished) {
[self sendActionsForControlEvents: UIControlEventValueChanged];
}];
}
else {
[self setValue: value animated: YES];
[self sendActionsForControlEvents: UIControlEventValueChanged];
}
}
}
else {
if (gesture.state == UIGestureRecognizerStateBegan) {
if (touchPoint.x <= trackArea.origin.x) {
if (self.value == self.minimumValue) return;
value = self.value - 1.5;
}
else {
if (self.value == self.maximumValue) return;
value = self.value + 1.5;
}
CGFloat duration = 0.1;
[UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveEaseInOut animations: ^{
[self setValue: value animated: YES];
} completion: ^(BOOL finished) {
[self sendActionsForControlEvents: UIControlEventValueChanged];
}];
}
}
}