在UIScrollView中,UIButton触摸会延迟

时间:2010-09-04 13:51:15

标签: ios uiscrollview uibutton touchescancelled

我在我的应用中遇到了一个小问题。

我基本上在UIButtons中添加了一系列UIScrollView作为子视图,这是nib的一部分。每次按下按钮,按钮突出显示之前都会有明显的延迟。在按钮变暗并且显示为选中之前,我基本上必须按住它约半秒钟。

我假设这是因为UIScrollView需要确定触摸是否是滚动,或者是否是针对子视图的触摸。

无论如何,我对如何继续有点不确定。我只想在按下按钮后立即显示该按钮。

感谢任何帮助!

修改

我已尝试将delaysContentTouches设置为 NO ,但滚动几乎不可能,因为我的大部分scrollView都填充了UIButtons

7 个答案:

答案 0 :(得分:48)

杰夫的解决方案并不适合我,但类似的解决方案是:http://charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state

除了在滚动视图子类中覆盖touchesShouldCancelInContentView之外,您仍需要将delaysContentTouches设置为false。最后,您需要为按钮返回true而不是false。以下是上述链接的修改示例。正如评论者建议的那样,它会专门检查UIControl而不是UIButton的任何子类,以便此行为适用于任何类型的控件。

<强>目标-C:

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        self.delaysContentTouches = false;
    }

    return self;
}

- (BOOL)touchesShouldCancelInContentView:(UIView *)view {
    if ([view isKindOfClass:UIControl.class]) {
        return true;
    }

    return [super touchesShouldCancelInContentView:view];
}

Swift 4:

override func touchesShouldCancel(in view: UIView) -> Bool {
    if view is UIControl {
        return true
    }
    return super.touchesShouldCancel(in: view)
}

答案 1 :(得分:40)

好的我通过继承UIScrollView并覆盖touchesShouldCancelInContentView

来解决这个问题

现在我标记为99的UIButton正确突出显示,我的滚动视图正在滚动!

myCustomScrollView.h

@interface myCustomScrollView : UIScrollView  {

}

@end

myCustomScrollView.m

@implementation myCustomScrollView

    - (BOOL)touchesShouldCancelInContentView:(UIView *)view
    {
        NSLog(@"touchesShouldCancelInContentView");

        if (view.tag == 99)
            return NO;
        else 
            return YES;
    }

答案 2 :(得分:26)

尝试将UIScrollView delaysContentTouches属性设置为NO。

答案 3 :(得分:1)

故事板解决方案:选择滚动视图,打开“属性检查器”并取消选中“延迟内容触摸”

enter image description here

答案 4 :(得分:1)

在Swift 3中:

import UIKit

class ScrollViewWithButtons: UIScrollView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        myInit()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        myInit()
    }

    private func myInit() {
        self.delaysContentTouches = false
    }

    override func touchesShouldCancel(in view: UIView) -> Bool {
        if view is UIButton {
            return true
        }
        return super.touchesShouldCancel(in: view)
    }
}

然后,您可以在IB或代码中使用此ScrollViewWithButtons

答案 5 :(得分:0)

现有的解决方案都不适合我。也许我的情况更独特。

我在UIButtons内有很多UIScrollView。当按下UIButton时,会向用户显示新的UIViewController。如果按下按钮并保持足够长的时间,该按钮将显示其按下状态。我的客户抱怨说,如果你点击太快,就不会出现压抑状态。

我的解决方案: 在UIButtons'tap方法中,我加载新UIViewController并在屏幕上显示,我使用

[self performSelector:@selector(loadNextScreenWithOptions:) 
           withObject:options 
           afterDelay:0.]

这会计划在下一个事件循环中加载下一个UIViewController。允许UIButton重绘的时间。 UIButton现在在加载下一个UIViewController之前显示其处于低迷状态。

答案 6 :(得分:0)

斯威夫特3:

scrollView.delaysContentTouches = false