Objective c 触摸UISlider可防止UIScrollView的滚动

Objective c 触摸UISlider可防止UIScrollView的滚动,objective-c,cocoa-touch,uiscrollview,uislider,Objective C,Cocoa Touch,Uiscrollview,Uislider,我在UIScrollview中有一个(垂直)UISlider。我希望能够更改滑块的值,并且在不抬起手指的情况下,向左或向右滚动scrollview 期望的行为: 在垂直UISlider内触碰,然后用手指向左或向右拖动,可使scrollview滚动 实际行为: 在垂直UISlider内触碰,然后用手指向左或向右拖动,在UIScrollview中不会移动。在UISlider外部触碰,然后拖动,将按预期滚动滚动滚动视图 UIView有一个名为exclusiveTouch的属性,它似乎与我的问题有关。我

我在UIScrollview中有一个(垂直)UISlider。我希望能够更改滑块的值,并且在不抬起手指的情况下,向左或向右滚动scrollview

期望的行为:

在垂直UISlider内触碰,然后用手指向左或向右拖动,可使scrollview滚动

实际行为:

在垂直UISlider内触碰,然后用手指向左或向右拖动,在UIScrollview中不会移动。在UISlider外部触碰,然后拖动,将按预期滚动滚动滚动视图

UIView有一个名为exclusiveTouch的属性,它似乎与我的问题有关。我试着把它设为“否”,但运气不好


那么,如何设置我的UISlider,使其下方的滚动视图能够响应源自UISlider内部的触摸?

您看到的是预期的行为

每个触摸事件仅由一个控件处理。
exclusiveTouch
实际上是防止其他触摸事件传递到其他视图

要想做你想做的事情,你必须做一些触摸操作。将事件传递给两个视图。您可以通过实现所有的
touchsbegind:
touchsmoved:
等方法来实现,并将事件传递给两个视图。您可以在中阅读有关该方法的更多信息。另一种方法是在滚动视图上的UIgestureRecognitor中执行事件处理,hit测试滑块并使用y-delta更新滑块的值。您可以在中阅读有关手势识别器和事件处理的更多信息


旁注:
转到“设置”应用程序,将开关切换一半(例如“飞机模式切换”),然后向下拖动。什么也不会发生。操作系统的其余部分的行为方式相同。你确定这是你真正想要做的互动吗?行为不同的应用程序通常会感到奇怪和陌生。

你的问题让我有点困惑。你说的是一个垂直的滑块,但是左右拖动

如果希望在拖动UISlider时滚动scrollview,正确的方法是

[mySlider addTarget:self action:@selector(sliderMoved:) forControlEvents:UIControlEventValueChanged];


希望这就是您想要的。

您是否尝试过子类化
UIScrollView
并实现
-(BOOL)touchshouldCancelIncontentView:(UIView*)视图
?根据苹果的文档:

// called before scrolling begins if touches have already been delivered to a subview of the scroll view. if it returns NO the touches will continue to be delivered to the subview and scrolling will not occur
// not called if canCancelContentTouches is NO. default returns YES if view isn't a UIControl

如果只返回
NO
,如果
视图是您的
UISlider
,这可能会执行您想要的操作,假设您的
UIScrollView
仅水平滚动。如果这不起作用,您可能必须执行自定义触摸处理(即覆盖
触摸开始:withEvent:
触摸更改:withEvent:
,等等)对于您的
UIScrollView
UISlider

,我认为您可以从示例中获得一些参考。在本示例中,演示了如何取消任何触摸或手势识别器,并将其应用于其他视图

希望这能引导你找到问题的解决办法,如果能让我知道的话


快乐编码:)

您需要将delaysContentTouches设置为NO并防止UISlider对象滚动,请检查下面的代码

mySlider.delaysContentTouches = NO;

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    if ([view isKindOfClass:[UISlider class]])
    {
        UITouch *touchEvent = [[event allTouches] anyObject];
        CGPoint locationEvent = [touchEvent locationInView:view];
        CGRect thumbRect;
        UISlider *mySlide = (UISlider*) view;
        CGRect trackRect = [mySlide trackRectForBounds:mySlide.bounds];
        thumbRect = [mySlide thumbRectForBounds:mySlide.bounds trackRect:trackRect value:mySlide.value];
        if (CGRectContainsPoint(thumbRect, locationEvent))
            return YES;
    }
    return NO;
}

+1表示期望/预期结果与实际结果。更多的问题应该这样做。+1表示“要做你想做的事情,你必须做一些触摸处理自己。”@morgancodes是的,可能有点模糊。我添加了两个基本的备选方案和相关文档的链接,以了解如何进行自己的触摸处理。感谢您的回复,但这不是我要问的。我试图弄清楚如何允许touchesMoved事件应用于UIScrollview,而不仅仅是scrollview中的UISlider。我想要一个垂直拖动来更改滑块的值,一个水平拖动来更改UIScrollview的位置,如果没有垂直滑块的话。
mySlider.delaysContentTouches = NO;

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view {
    if ([view isKindOfClass:[UISlider class]])
    {
        UITouch *touchEvent = [[event allTouches] anyObject];
        CGPoint locationEvent = [touchEvent locationInView:view];
        CGRect thumbRect;
        UISlider *mySlide = (UISlider*) view;
        CGRect trackRect = [mySlide trackRectForBounds:mySlide.bounds];
        thumbRect = [mySlide thumbRectForBounds:mySlide.bounds trackRect:trackRect value:mySlide.value];
        if (CGRectContainsPoint(thumbRect, locationEvent))
            return YES;
    }
    return NO;
}