【问题标题】:UIButton stops UIScrollView scrolling in SwiftUIButton 在 Swift 中停止 UIScrollView 滚动
【发布时间】:2014-10-10 21:56:02
【问题描述】:

我的 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)

和按钮点击的代码:

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

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

【问题讨论】:

    标签: ios button uiscrollview swift


    【解决方案1】:

    尝试将UIScrollViewdelaysContentTouches 属性设置为NO

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


    Reference(来自文档):
    • canCancelContentTouches:控制内容视图中的触摸是否始终导致跟踪的布尔值。

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

    【讨论】:

    • 在我的 UIScrollVIew 的 initWithSize 方法中将两个属性都设置为 YES 但它不起作用:(。
    • 对不起,我的错。对于 iOS 7,将 delaysContentTouches 设置为 NO。
    • 测试它,但我找到了解决方案。我会写一个答案并解释为什么它有效和无效,因为我找到的答案有效但没有得到很好的解释。
    【解决方案2】:

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

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

    先决条件: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,即使按钮被触摸,您也可以滚动,但不会像 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 文件。

    如果你现在运行你的应用程序,你会看到在一个按钮触摸时 layoutSubviewstouchesShouldBegin 都被调用了。滚动有效。它可以工作,但仍然不会调用按钮的方法。原因是 touchEvent 被取消,并且在取消触摸后允许跟踪。阅读docs (CTRL + F "canCancelContentTouches"):

    如果此属性的值为 YES 并且内容中的视图具有 开始跟踪触摸它的手指,如果用户拖动手指 足以启动滚动,视图会收到一个 touchesCancelled:withEvent: 消息和滚动视图处理 像滚动一样触摸。如果该属性的值为 NO,则滚动 一旦内容显示,无论手指移动,视图都不会滚动 视图开始跟踪。

    由于您将按钮设置为:

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

    myButtonPressed 将不会被调用,因为 UIControlEventTouchUpOutside 发生了。如果您将其更改为:

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

    并再次运行代码,您不仅可以滚动,还可以单击按钮并进一步滚动,因为您的按钮现在会在发生 EventTouchCancel 时调用选择器,因为您允许 UISV 将 touchBegin 转换为 touchCancelled :

    self.canCancelContentTouches = YES;
    

    不要忘记覆盖(添加):

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

    没有它就行不通。请提供任何反馈,因为我希望这将很快起作用,我将很快开始使用。希望它有所帮助。 Gl & hf :)

    【讨论】:

      猜你喜欢
      • 2016-10-12
      • 2015-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 1970-01-01
      • 2011-07-01
      • 2021-02-14
      相关资源
      最近更新 更多