Nor*_*ert 18 uislider uigesturerecognizer ios uitapgesturerecognizer
我想要的是一个UISlider
让用户不仅可以在他开始时滑动thumbRect
,而且还可以在其他地方点击的时候滑动.当用户点击滑块但在滑块之外时thumbRect
,滑块应跳转到该值,然后仍然保持用户的滑动手势.
到目前为止我尝试过的是在这个建议中实现UIGestureRecognizer的子类.当它thumbRect
发生在外面某处的触地时,它就开始了.问题是滑块设置其值但随后进一步滑动手势被忽略,因为触摸识别器已经窃取了触摸.
如何实现滑块,您可以在任何地方点按但仍然可以立即滑动?
编辑:ali59a非常友好地添加了我现在所做的一个例子.这需要再次抬起手指,之后我可以触摸并拖动滑动(水龙头不是我想要的,我需要立即'触摸和滑动').
Dav*_*mes 23
我不确定你是否还在寻找答案,但我今天只是在看这个问题; 我设法让它为我工作.
它的关键是使用a UILongPressGestureRecognizer
而不是a UITapGestureRecognizer
,然后我们可以minimumPressDuration
将识别器设置为0; 使它充当水龙头识别器,除了你现在可以实际检查它的状态.
把ali59a建议起来对你有用,只需UITapGestureRecognizer
用a 代替UILongPressGestureRecognizer
.但是,我发现这似乎并没有将thumbRect直接放在我的拇指下面.它看起来有点偏离我.
我为我的项目创建了自己的UISlider子类,这就是我为我实现"点击和滑动功能"的方法.
在我的init
方法中:
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(tapAndSlide:)];
longPress.minimumPressDuration = 0;
[self addGestureRecognizer:longPress];
Run Code Online (Sandbox Code Playgroud)
然后我的tapAndSlide:
方法:
- (void)tapAndSlide:(UILongPressGestureRecognizer*)gesture
{
CGPoint pt = [gesture locationInView: self];
CGFloat thumbWidth = [self thumbRect].size.width;
CGFloat value;
if(pt.x <= [self thumbRect].size.width/2.0)
value = self.minimumValue;
else if(pt.x >= self.bounds.size.width - thumbWidth/2.0)
value = self.maximumValue;
else {
CGFloat percentage = (pt.x - thumbWidth/2.0)/(self.bounds.size.width - thumbWidth);
CGFloat delta = percentage * (self.maximumValue - self.minimumValue);
value = self.minimumValue + delta;
}
if(gesture.state == UIGestureRecognizerStateBegan){
[UIView animateWithDuration:0.35 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
[self setValue:value animated:YES];
[super sendActionsForControlEvents:UIControlEventValueChanged];
} completion:nil];
}
else [self setValue:value];
if(gesture.state == UIGestureRecognizerStateChanged)
[super sendActionsForControlEvents:UIControlEventValueChanged];
}
Run Code Online (Sandbox Code Playgroud)
我还使用一种方法返回我的自定义thumbRect的框架:
- (CGRect)thumbRect {
CGRect trackRect = [self trackRectForBounds:self.bounds];
return [self thumbRectForBounds:self.bounds trackRect:trackRect value:self.value];
}
Run Code Online (Sandbox Code Playgroud)
我也让我的滑块动画显示用户首次点击的位置,超过0.35秒.我认为这看起来很甜蜜,所以我把它包含在那个代码中.如果您不想这样,只需尝试:
- (void)tapAndSlide:(UILongPressGestureRecognizer*)gesture
{
CGPoint pt = [gesture locationInView: self];
CGFloat thumbWidth = [self thumbRect].size.width;
CGFloat value;
if(pt.x <= [self thumbRect].size.width/2.0)
value = self.minimumValue;
else if(pt.x >= self.bounds.size.width - thumbWidth/2.0)
value = self.maximumValue;
else {
CGFloat percentage = (pt.x - thumbWidth/2.0)/(self.bounds.size.width - thumbWidth);
CGFloat delta = percentage * (self.maximumValue - self.minimumValue);
value = self.minimumValue + delta;
}
[self setValue:value];
if(gesture.state == UIGestureRecognizerStateChanged)
[super sendActionsForControlEvents:UIControlEventValueChanged];
}
Run Code Online (Sandbox Code Playgroud)
我希望这是有道理的,并帮助你.
Jop*_*ped 13
我将DWilliames提供的答案转换为Swift
在你的viewDidAppear()里面
let longPress = UILongPressGestureRecognizer(target: self.slider, action: Selector("tapAndSlide:"))
longPress.minimumPressDuration = 0
self.addGestureRecognizer(longPress)
Run Code Online (Sandbox Code Playgroud)
类文件
class TapUISlider: UISlider
{
func tapAndSlide(gesture: UILongPressGestureRecognizer)
{
let pt = gesture.locationInView(self)
let thumbWidth = self.thumbRect().size.width
var value: Float = 0
if (pt.x <= self.thumbRect().size.width / 2)
{
value = self.minimumValue
}
else if (pt.x >= self.bounds.size.width - thumbWidth / 2)
{
value = self.maximumValue
}
else
{
let percentage = Float((pt.x - thumbWidth / 2) / (self.bounds.size.width - thumbWidth))
let delta = percentage * (self.maximumValue - self.minimumValue)
value = self.minimumValue + delta
}
if (gesture.state == UIGestureRecognizerState.Began)
{
UIView.animateWithDuration(0.35, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut,
animations:
{
self.setValue(value, animated: true)
super.sendActionsForControlEvents(UIControlEvents.ValueChanged)
},
completion: nil)
}
else
{
self.setValue(value, animated: false)
}
}
func thumbRect() -> CGRect
{
return self.thumbRectForBounds(self.bounds, trackRect: self.bounds, value: self.value)
}
}
Run Code Online (Sandbox Code Playgroud)
您应该在您的UISlider
.
示例:
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(sliderTapped:)];
[_slider addGestureRecognizer:tapGestureRecognizer];
Run Code Online (Sandbox Code Playgroud)
在 sliderTapped 中,您可以获取位置并更新 slider 的值:
- (void)sliderTapped:(UIGestureRecognizer *)gestureRecognizer {
CGPoint pointTaped = [gestureRecognizer locationInView:gestureRecognizer.view];
CGPoint positionOfSlider = _slider.frame.origin;
float widthOfSlider = _slider.frame.size.width;
float newValue = ((pointTaped.x - positionOfSlider.x) * _slider.maximumValue) / widthOfSlider;
[_slider setValue:newValue];
}
Run Code Online (Sandbox Code Playgroud)
我在这里创建一个示例:https ://github.com/ali59a/tap-and-slide-in-a-UISlider
归档时间: |
|
查看次数: |
10136 次 |
最近记录: |