UISlider使用
场景:
文字大小控制页面是UISrollView的第三个page,文字大小控制页由UISlider组成。
问题:
UISlider的滑动小块难以选中,滑动时容易滑动到UIScrollView,两控件滑动手势冲突。
方案:
1、 放大UISlider的滑动小块的触碰面积,两控件手势仍然冲突,无法解决问题。
放大方法:继承UISlider,重写以下方法
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value{
CGRect frame = [super thumbRectForBounds:bounds trackRect:rect value:value];
//放大thumb图片
frame.origin.y -= 20;
frame.origin.x -= 20;
frame.size.height += 40;
frame.size.width += 40;
return frame;
}
2、 禁用UIScrollView的滑动,两控件手势无冲突,解决问题。需求要求保留UIScrollView滑动功能,此方案不通过。
_scrollView.scrollEnabled = NO;
3、继续查证发现,直接拖动UISlider,此时touch时间在150ms以内,UIScrollView会认为是拖动自己,从而拦截了event,导致UISlider接受不到滑动的event。但是只要按住UISlider一会再拖动,此时此时touch时间超过150ms,因此滑动的event会发送到UISlider上。
新建分类重写UIScrollView的hittest方法:
分类声明了一个属性,传入可能会发生冲突的类型,命中冲突的类型就把UIScrollView的滚动禁用,解决手势冲突,解决问题。
我们还能使用方案1放大小滑块面积配合使用,效果更佳。
@interface UIScrollView (TPHitTestJudge)
///需要判断会发生滑动手势冲突的类型
@property (nonatomic, strong) Class judgeClass;
@end
#import "UIScrollView+TPHitTestJudge.h"
#import "objc/runtime.h"
static NSString *const propertyKey = @"UIScrollViewHitTestJudgeClass";
@implementation UIScrollView (TPHitTestJudge)
- (void)setJudgeClass:(Class)judgeClass {
objc_setAssociatedObject(self, &propertyKey, judgeClass, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (Class)judgeClass {
return objc_getAssociatedObject(self, &propertyKey);
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
/*
直接拖动UISlider,此时touch时间在150ms以内,UIScrollView会认为是拖动自己,从而拦截了event,导致UISlider接受不到滑动的event。但是只要按住UISlider一会再拖动,此时此时touch时间超过150ms,因此滑动的event会发送到UISlider上。
*/
UIView *view = [super hitTest:point withEvent:event];
if([view isKindOfClass:self.judgeClass]) {
self.scrollEnabled = NO;
} else {
self.scrollEnabled = YES;
}
return view;
}
@end
使用方法:
_scrollView.judgeClass = [UISlider class];
补充:
在本次UISlider的使用里,ThumbImage是一张有阴影的切图,切图的左边右边有透明的区域。直接设置的话,导致在视觉效果上,UISlider拉到边界还与边界有一定距离
我们还可以通过重写下面方法解决。参数bounds是UISlider的bounds,参数rect是滑块的在UISlider中的位置,参数value是UISlider的当前值,返回值是滑块在view上的位置。
- (CGRect)thumbRectForBounds:(CGRect)bounds trackRect:(CGRect)rect value:(float)value{
//thumb图片左右有空白,修正偏移
rect.origin.x -= 5;
rect.size.width += 10;
CGRect frame = [super thumbRectForBounds:bounds trackRect:rect value:value];
//放大thumb图片
frame.origin.y -= 20;
frame.origin.x -= 20;
frame.size.height += 40;
frame.size.width += 40;
return frame;
}
本文地址:https://blog.csdn.net/qq_27539955/article/details/107351267