UIButton在Swift中停止UIScrollView滚动

时间:2014-08-18 02:37:11

标签: ios button uiscrollview swift

我的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区域可靠滚动的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

尝试将delaysContentTouches的{​​{1}}属性设置为UIScrollView

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

<小时/> Reference(来自文档):

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

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

答案 1 :(得分:0)

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

答案取自: ScrollView not scrolling when dragging on buttons

PREREQUSITS:UIScrollView子类,Xcode 5.1.1,iOS 7.1。,UIBut在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,你甚至可以滚动触摸按钮,但触摸事件不会像docs中所写的那样被注册(CTRL + F“touchesShouldBegin”)

  

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

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

解决方案2 - 完全

1.增加:

self.canCancelContentTouches = YES;

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

2.增加:

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

到您的子类UISV .m文件。

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

  

如果此属性的值为YES并且内容中的视图具有   开始跟踪触摸它的手指,如果用户拖动手指   足以启动滚动,视图收到一个   touchesCancelled:withEvent:message和滚动视图处理   触摸滚动。如果此属性的值为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;
}

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