Increasing a thumbs “click area” in UISlider

梦想与她 提交于 2019-11-30 08:06:28

You have to override thumbRectForBounds:trackRect:value: in a custom subclass (instead of calling the method yourself like you do in your code, which does nothing except returning a value that you don't even bother to retrieve).

thumbRectForBounds:trackRect:value: is not a method to set the tumb rect, but to get it. The slider will internally call this thumbRectForBounds:trackRect:value: method to know where to draw the thumb image, so you need to override it — as explained in the documentation — to return the CGRect you want (so that it will be 35x35px as you wish).

Borut Tomazin

Updated for Swift 3.0 and iOS 10

private func generateHandleImage(with color: UIColor) -> UIImage {
    let rect = CGRect(x: 0, y: 0, width: self.bounds.size.height + 20, height: self.bounds.size.height + 20)

    return UIGraphicsImageRenderer(size: rect.size).image { (imageContext) in
        imageContext.cgContext.setFillColor(color.cgColor)
        imageContext.cgContext.fill(rect.insetBy(dx: 10, dy: 10))
    }
}

Calling:

self.sliderView.setThumbImage(self.generateHandleImage(with: .white), for: .normal)

Original answer:

By far the easiest method is just to increase the size of the thumb image with invisible border around it:

- (UIImage *)generateHandleImageWithColor:(UIColor *)color
{
    CGRect rect = CGRectMake(0.0f, 0.0f, self.bounds.size.height + 20.f, self.bounds.size.height + 20.f);
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.f);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, color.CGColor);
    CGContextFillRect(context, CGRectInset(rect, 10.f, 10.f));

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

And than adding this image to slider:

[self.sliderView setThumbImage:[self generateHandleImageWithColor:[UIColor redColor]] forState:UIControlStateNormal];

You can check my double slider project

In summary, I implemented the hit test method so the beginTrackingWithTouch is invoked.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (CGRectContainsPoint(self.leftHandler.frame, point) || CGRectContainsPoint(self.rightHandler.frame, point)) {
        return self;
    }

    return [super hitTest:point withEvent:event];
}

Check the class for further details

why you wanna go for custom slider while you can change the area of a default slider ;)

take a look at this code it worked for me to increase the touch area of my UISlider hope it helps you too

CGRect sliderFrame = yourSlider.frame;
sliderFrame.size.height = 70.0;
[yourSlider setFrame:sliderFrame];

I also had this problem and solved it by overriding

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event

method. You can return YES for those points, that you want to be touched.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!