自定义 UISlider - 增加“热点”大小
Posted
技术标签:
【中文标题】自定义 UISlider - 增加“热点”大小【英文标题】:Custom UISlider - Increase "hot spot" size 【发布时间】:2012-11-02 13:32:48 【问题描述】:我有一个自定义 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];
【问题讨论】:
你可以作弊——在你的拇指图像周围添加一个透明像素的边框——这会增加它的大小而不会让它看起来有任何不同:) 如果我这样做了,我将无法将滑块设置为 0 或 1。(就像它会设置为零,但它看起来不像是由于透明图片左侧/右侧的边框。) 因此,还要在轨道图像的左侧/右侧添加填充。然后,补偿在您的代码中无法完全达到 0 或 1。 点击这个链接erfan-ali-31.blogspot.in/2011/10/…它的工作,也在设备中测试 【参考方案1】:我最终继承了 UISlider 并覆盖了这个方法:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
CGRect bounds = self.bounds;
bounds = CGRectInset(bounds, -10, -15);
return CGRectContainsPoint(bounds, point);
这会将可触摸区域的左右扩大 10 像素,上下扩大 15 像素。
【讨论】:
这似乎在 ios7 上运行良好。我想加厚轨道的边界,所以我将 UISlider 子类化并重新实现 (CGRect)trackRectForBounds:(CGRect)bounds,但是可点击区域非常小。以上解决了这个问题 这在iOS6上好像没有生效,但是在iOS7上可以。对 iOS 6 支持有何建议?【参考方案2】:此解决方案适用于 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
【讨论】:
thumbImageForState(UIControlState.Normal)
可以返回 nil 如果不使用发布在 :***.com/questions/21313796/… 的自定义图像。正如 Rudolf Adamkovic 所建议的,子类化解决了获取拇指大小的问题。
谢谢托马斯!这个答案对我帮助很大!【参考方案3】:
斯威夫特 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)
【讨论】:
【参考方案4】:我最终使用了它,它对我来说效果很好。
发布此答案,以便对某人有所帮助。
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()
【讨论】:
【参考方案5】:您也可以只增加图像大小,这将导致滑块拇指大小的增加。
如果您需要保持图像尺寸不要太大但调整滑块大小,只需在图像内容周围添加透明空间。
如果您在 UITableViewCell 中使用滑块,问题还在于 tableview 处理手势就在滑块之前。要更改这一点,请使用以下解决方案: https://***.com/a/37751635/2150954 我认为将他的代码翻译成Objective C并不太难。
【讨论】:
我不认为图像中的间距可以工作,由于间距,图像中的擦洗器永远不会完全接触到滑块的左侧或滑行侧。【参考方案6】:调整框架大小并将图像对齐更改为所需的。您可以使其对齐居中、左、右、上或下。这样做:
CGRect newFrame = sliderHandle.frame;
CGRectSetWidth(newFrame, 80);
CGRectSetHeight(newFrame, 80);
[sliderHandle setFrame:newFrame];
[sliderHandle setContentMode:UIViewContentModeCenter];
所以你的触摸框会更大,图像比例会保持不变。
【讨论】:
这只是调整滑块的可见高度和宽度,并不会增加触摸区域。 您还可以调整实际滑块视图的大小,它会收集触摸以上是关于自定义 UISlider - 增加“热点”大小的主要内容,如果未能解决你的问题,请参考以下文章