UIPageViewController with internal UISlider controller - increases the hit area of ​​the slider

I have multiple controllers in my PageViewController and in one controller I have multiple sliders. Now there is a problem that the user has to touch exactly the circle of the slider (I'm not sure of the correct expression, thumb?), Which is the moving part) and I would like to enlarge the area in which the slider reacts, not the whole PageViewController. I tried these solutions but it didn't help:

  • thumbRectForBounds:

    - (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
    {
        return CGRectInset ([super thumbRectForBounds:bounds trackRect:rect value:value], 15, 15);
    }
    
          

  • Enlarge hitTest area:

    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        if (CGRectContainsPoint(CGRectInset(self.frame, 200, 200), point) || CGRectContainsPoint(CGRectInset(self.frame, 200, 200), point)) {
             return self;
        }
        return [super hitTest:point withEvent:event];
    }
    
          

I have these methods in my custom slider class because I would like to reuse it. Last thing I found and haven't tried yet is to create an object layer above the slider that "takes" the gesture and disables the PageViewController, but I'm not sure how to do this and I'm not sure if it's a good / best solution.

+3


source to share


3 answers


I'm not a big fan of the UISlider component because, as you noticed, it's not trivial to increase the hit area of ​​a real slider. I would highly recommend that you reuse the UISlider using a stiffening gesture for a better user experience:

I am. create slider background with separate UIImageView with slider image. II. create PanGesture:

UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:);
[imageView addGestureRecognizer:pan];

      

III. implement handlePan method:



- (IBAction)handlePan:(UIPanGestureRecognizer *)recognizer {

    //pan (slide) begins
    CGPoint translation = [recognizer locationInView:self.view];
    translation.y = self.slideImage.center.y;
    self.slideImage.center = translation;

    if(recognizer.state == UIGestureRecognizerStateEnded) {
        LTDebugLog(@"\n\n PAN, with spot: %f\n\n", self.slideImage.center.x);
        //do something after user is done sliding
    }
}

      

The big advantage of this method is that you will have a much better user experience as you can make the flexible UIImageView as large as you want.

Alternatively, you can subclass the UISlider and increase the whitespace in there, although this gives mixed results in my experience.

Hope it helps

+2


source


In the class, CustomSlider

override the class thumbRectForBounds

:

Just return the value of the rectangle as you like:

- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value
{
    return CGRectMake (bounds.origin.x, bounds.origin.y, yourWidthValue, yourHeightValue );
}

      

Change yourWidthValue

and as yourHeightValue

per your requirement. And then when using



Create an object as shown below:

CustomSlider *slider  = [[CustomSlider alloc] initWithFrame:CGRectMake(0, 0, 300, 20)];
[slider thumbRectForBounds: slider.bounds trackRect:slider.frame value:15.f]; // change values as per your requirements.

      

Hope it helps.

+1


source


Create a custom thumb image with a large free margin and set it on your slider like:

[theSlider setThumbImage:[UIImage imageNamed:@"slider_thumb_with_margins"] forState:UIControlStateNormal];

      

To make an image, get a copy of the system's thumb image using any of several UIKit artwork extractors (just search the web for one). Open your thumbnail image in Photoshop and resize your canvas to twice the size of the box you want to add. Make sure you resize the canvas, not the image size, as the image size will stretch the image to fill the new size. This will put white space around the thumb, which will be part of the testing area, but since it is transparent, it will not change the appearance of the slider.

+1


source







All Articles