UIButton在Swift中停止UIScrollView滚动

我的UIScrollView区域滚动完美,除非用户按下其中一个按钮:

var button:UIButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton button.frame = CGRectMake(0,0,self.width, self.menuHeight) button.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside) button.tag = Int(itemNo) scrollView.addSubview(button) 

和buttonClicked代码:

 func buttonClicked(sender:UIButton) { var tag = sender.tag println(tag) } 

看起来TouchUpInside方法即使在用户将取景器移离按钮时也能保持控制。 让我的UIScrollView区域可靠滚动的最佳方法是什么?

尝试将UIScrollViewdelaysContentTouches属性设置为NO

此外,您可以将canCancelContentTouches属性设置为YES 。 (默认为是,但以防万一。)


参考 (来自docs):

  • canCancelContentTouches :一个布尔值,用于控制内容视图中的触摸是否始终导致跟踪。

  • delaysContentTouches :一个布尔值,用于确定滚动视图是否延迟了触摸手势的处理。

这可能适用于swift。 它在iOS 7.1中适用于我。 Xcode 5.1.1没有swift。

答案取自: 拖动按钮时ScrollView不滚动

PREREQUSITS:UIScrollView子类,Xcode 5.1.1,iOS 7.1。,UIButton在UISV滚动时保持固定位置,UISV中的一些按钮作为子视图添加

理论:

– 在UISCV子类的.m文件中实现:

 - (void)layoutSubviews { NSLog(@" layoutSubviews - contentOffset.x = %f ",self.contentOffset.x); } - (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view { UITouch *touch = [touches anyObject]; CGPoint positionInScene = [touch locationInView:self]; NSLog(@" touchesShouldBegin - Toched point - (%f,%f) -",positionInScene.x,positionInScene.y); return YES; } 

如果您现在在按钮框架(已添加)之外滚动SV,您将看到正在调用layoutSubview方法,并在滚动时更改contentOffset位置。 我使用.x坐标,因为我使用水平滚动(如果你有垂直滚动,请使用.y)。 但是,如果单击按钮,您将看到touchesShouldBegin被调用时触摸位置正确,即按下按钮。 但是,如果您将手指放在按钮上并尝试拖动,则不会发生滚动,也不会调用layoutSubviews。 这是问题所在。 现在你将有你的触摸,但不是你的滚动。 自从每次触摸停止滚动后,您拥有的按钮越多,所以“滚动机会”越少。

解决方案1 ​​ – 部分

如果你在touchesShouldBegin中返回NO,你甚至可以滚动按钮被触摸但是触摸事件不会像在文档中写的那样被注册(CTRL + F“touchesShouldBegin”)

返回值如果您不希望滚动视图发送要查看的事件消息,则返回NO。 如果要查看接收这些消息,请返回YES(默认值)。

因此,您的滚动视图不会注册任何触摸事件。 在这个链接上有人建议使用UIImageViews而不是按钮并使用它们的帧大小。 使用框架大小,您可以检查positionInScene(CGPoint)是否适合任何框架,如果它确实调用了按钮工作的方法。

解决方案2 – 完全

1.新增:

 self.canCancelContentTouches = YES; 

到init方法中的子类UISV .m文件。

2.增加:

 - (BOOL)touchesShouldCancelInContentView:(UIView *)view { return YES; } 

到您的子类UISV .m文件。

如果您现在运行您的应用程序,您将看到触摸按钮时调用layoutSubviewstouchesShouldBegin 。 滚动工作。 它工作但仍然没有调用您的按钮的方法。 原因是touchEvent被取消,触摸被取消后,正在允许跟踪。 阅读文档 (CTRL + F“canCancelContentTouches”):

如果此属性的值为YES并且内容中的视图已开始跟踪手指触摸它,并且如果用户拖动手指足以启动滚动,则视图将接收touchesCancelled:withEvent:消息并且滚动视图处理触摸滚动。 如果此属性的值为NO,则在内容视图开始跟踪后,无论手指移动,滚动视图都不会滚动。

由于您将按钮设置为:

 [myButton addTarget:self action:@selector(myButtonPressed:) forControlEvents:UIControlEventTouchUpOutside]; 

自从UIControlEventTouchUpOutside发生以来,不会调用myButtonPressed。 如果您将其更改为:

 [flagButton addTarget:self action:@selector(myButtonPressed:) forControlEvents:UIControlEventTouchCancel]; 

再次运行代码你不仅会滚动而是按钮点击并进一步滚动,因为你的按钮现在调用选择器时会发生EventTouchCancel,因为你让UISV将touchBegin变换为touchCancelled并且:

 self.canCancelContentTouches = YES; 

别忘了覆盖(添加):

 - (BOOL)touchesShouldCancelInContentView:(UIView *)view { return YES; } 

没有它,它将无法运作。 请提供任何反馈,因为我希望这将很快起作用,我将很快开始使用。 希望它有所帮助。 G1&hf 🙂