自定义 UISlider - 增加“热点”大小

问题描述 投票:0回答:7

我有一个自定义的 UISlider,由于“拇指图像”的大小,对于大手指的人来说相对难以抓住和滑动。有没有办法在不改变图像大小的情况下增加可点击/可拖动区域的大小?

这是我用于创建自定义滑块的代码(如果有帮助的话):

[slider setMaximumTrackImage:[[UIImage imageNamed:@"max.png"]
                                             resizableImageWithCapInsets:UIEdgeInsetsMake(0, 20, 0, 20)]
                                   forState:UIControlStateNormal];
[slider setMinimumTrackImage:[[UIImage imageNamed:@"min.png"]
                                             resizableImageWithCapInsets:UIEdgeInsetsMake(0, 20, 0, 20)]
                                   forState:UIControlStateNormal];
[slider setThumbImage:[UIImage imageNamed:@"thumb.png"]
                            forState:UIControlStateNormal];
objective-c ios uislider
7个回答
27
投票

我最终对 UISlider 进行子类化并重写此方法:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
    CGRect bounds = self.bounds;
    bounds = CGRectInset(bounds, -10, -15);
    return CGRectContainsPoint(bounds, point);
}

这会将可触摸区域向左和向右扩展 10 像素,在顶部和底部扩展 15 像素。


8
投票

此解决方案适用于 iOS 8:

class ExtUISlider: UISlider {

    var thumbTouchSize : CGSize = CGSizeMake(50, 50)

    override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
        let bounds = CGRectInset(self.bounds, -thumbTouchSize.width, -thumbTouchSize.height);
        return CGRectContainsPoint(bounds, point);
    }

    override func beginTrackingWithTouch(touch: UITouch, withEvent event: UIEvent) -> Bool {
        let thumbPercent = (value - minimumValue) / (maximumValue - minimumValue)
        let thumbSize = thumbImageForState(UIControlState.Normal)!.size.height
        let thumbPos = CGFloat(thumbSize) + (CGFloat(thumbPercent) * (CGFloat(bounds.size.width) - (2 * CGFloat(thumbSize))))
        let touchPoint = touch.locationInView(self)

        return (touchPoint.x >= (thumbPos - thumbTouchSize.width) &&
            touchPoint.x <= (thumbPos + thumbTouchSize.width))
    }
}

感谢这篇文章:http://www.mpatric.com/2009-04-15-more-responsive-sliders-on-the-iphone


8
投票

斯威夫特3

UISlider
的子类,增加了触摸面积

class CustomSlider: UISlider {

    private var thumbTouchSize = CGSize(width: 40, height: 40)

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let increasedBounds = bounds.insetBy(dx: -thumbTouchSize.width, dy: -thumbTouchSize.height)
        let containsPoint = increasedBounds.contains(point)
        return containsPoint
    }

    override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
        let percentage = CGFloat((value - minimumValue) / (maximumValue - minimumValue))
        let thumbSizeHeight = thumbRect(forBounds: bounds, trackRect:trackRect(forBounds: bounds), value:0).size.height
        let thumbPosition = thumbSizeHeight + (percentage * (bounds.size.width - (2 * thumbSizeHeight)))
        let touchLocation = touch.location(in: self)
        return touchLocation.x <= (thumbPosition + thumbTouchSize.width) && touchLocation.x >= (thumbPosition - thumbTouchSize.width)
    }
}

3
投票

我最终使用了这个,它对我来说效果很好。

发布此答案,以便对某人有所帮助。

import UIKit

class CustomSlider: UISlider {

/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
    // Drawing code
}
*/
// Increase slider height
   override func trackRect(forBounds bounds: CGRect) -> CGRect {
    let customBounds: CGRect = CGRect(origin: bounds.origin, size: CGSize(width: bounds.size.width, height: 5.0))
    return customBounds
}



override func thumbRect(forBounds bounds: CGRect, trackRect rect: CGRect, value: Float) -> CGRect {
    return super.thumbRect(
        forBounds: bounds, trackRect: rect, value: value)


}

// Increase Thumb hot spot clickable area
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    var bounds: CGRect = self.bounds
    bounds = bounds.insetBy(dx: -10, dy: -10);
    return bounds.contains(point);

}

override func awakeFromNib() {
    // Configure Volume slider
    let thumbImageNormal = UIImage.init(named:"thumb")
    self.setThumbImage(thumbImageNormal, for: .normal)

    super.awakeFromNib()
}

}

1
投票

您也可以增加图像尺寸,这将导致滑块拇指尺寸的增加。

  1. 如果您需要将图像尺寸设置得不太大,但调整滑块尺寸,只需在图像内容周围添加透明空间即可。 enter image description here

  2. 如果您在 UITableViewCell 中使用滑块,问题还在于 tableview 处理手势就在滑块之前。要更改此设置,请使用以下解决方案: https://stackoverflow.com/a/37751635/2150954 我认为把他的代码翻译成 Objective C 并不太难。


0
投票
这是

Thomas原始答案的修改版本

Swift 4 和 Swift 5

class IncreasedAreaSlider: UISlider { let thumbTouchSize = CGSize(width: 50, height: 50) override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { let bounds = self.bounds.insetBy(dx: -thumbTouchSize.width, dy: -thumbTouchSize.height) return bounds.contains(point) } override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool { let thumbPercent = (value - minimumValue) / (maximumValue - minimumValue) let thumbSize = thumbImage(for: .normal)!.size.height let thumbPos = CGFloat(thumbSize) + (CGFloat(thumbPercent) * (CGFloat(bounds.size.width) - (2 * CGFloat(thumbSize)))) let touchPoint = touch.location(in: self) return (touchPoint.x >= (thumbPos - thumbTouchSize.width) && touchPoint.x <= (thumbPos + thumbTouchSize.width)) } }
    

-1
投票
调整框架大小并将图像对齐方式更改为所需的对齐方式。您可以将其设置为居中、左对齐、右对齐、上对齐或下对齐。这样做:

CGRect newFrame = sliderHandle.frame; CGRectSetWidth(newFrame, 80); CGRectSetHeight(newFrame, 80); [sliderHandle setFrame:newFrame]; [sliderHandle setContentMode:UIViewContentModeCenter];
所以你的触摸框会变大,图像比例保持不变。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.