ios UIButton 触摸在 UIScrollView 中延迟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3642547/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:39:43  来源:igfitidea点击:

UIButton touch is delayed when in UIScrollView

iosuiscrollviewuibuttontouchescancelled

提问by Jeff

I'm running into a small issue in my app.

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

I essentially have a series of UIButtonsadded as subviews in a UIScrollViewwhich is part of a nib. Every time I tap on a button there is a noticeable delay before the button is highlighted. I essentially have to hold it for about half a second before the button dims and appears selected.

我基本上在UIButtons作为UIScrollView笔尖一部分的 a中添加了一系列子视图。上的一个按钮我每次抽头有突出显示该按钮之前明显的延迟。我基本上是有选择的按钮变暗,似乎之前举行它大约半秒。

I'm assuming this is because the UIScrollViewneeds to determine if the touch is a scroll or if it's a touch that is meant for a subview.

我假设这是因为UIScrollView需要确定触摸是滚动还是用于子视图的触摸。

Anyways, I'm a little unsure on how to proceed. I simply want the button to appear selected as soon as I tap it.

无论如何,我有点不确定如何继续。我只是想让按钮在我点击后立即显示为选中状态。

Any help is appreciated!

任何帮助表示赞赏!

Edit:

编辑:

I've tried setting delaysContentTouchesto NObut scrolling becomes almost impossible since a majority of my scrollView is filled with UIButtons.

我试过设置delaysContentTouchesNO但滚动变得几乎不可能,因为我的大部分 scrollView 都充满了UIButtons.

采纳答案by Jeff

Ok I've solved this by subclassing UIScrollViewand overriding touchesShouldCancelInContentView

好的,我已经通过子类化UIScrollView和覆盖解决了这个问题touchesShouldCancelInContentView

Now my UIButtonthat was tagged as 99 highlights properly and my scrollview is scrolling!

现在我的UIButton那个被正确地标记为 99 个高亮并且我的滚动视图正在滚动!

myCustomScrollView.h:

myCustomScrollView.h:

@interface myCustomScrollView : UIScrollView  {

}

@end

and myCustomScrollView.m:

myCustomScrollView.m

@implementation myCustomScrollView

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

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

回答by jlong64

Jeff's solution wasn't quite working for me, but this similar one does: http://charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state

杰夫的解决方案对我来说不是很有效,但这个类似的解决方案确实如此:http: //charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state

In addition to overriding touchesShouldCancelInContentViewin your scroll view subclass, you still need to set delaysContentTouchesto false. Lastly, you need to return truerather than falsefor your buttons. Here's a modified example from the above link. As commenters suggested, it checks for any subclass of UIControlrather than UIButtonspecifically so that this behavior applies to any type of control.

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

Objective-C:

目标-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:

斯威夫特 4:

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

回答by Vladimir

Try to set UIScrollView delaysContentTouchesproperty to NO.

尝试将 UIScrollViewdelaysContentTouches属性设置为 NO。

回答by José

Storyboard solution: Select the scroll view, open the "Attributes Inspector" and uncheck "Delays Content Touches"

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

enter image description here

在此处输入图片说明

回答by Simon Reggiani

In Swift 3:

在 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)
    }
}

You can then use this ScrollViewWithButtonsin IB or in code.

然后您可以ScrollViewWithButtons在 IB 或代码中使用它。

回答by Oubaida AlQuraan

Swift 3 :

斯威夫特3:

scrollView.delaysContentTouches = false

回答by Brad Goss

None of the existing solutions worked for me. Maybe my situation is more unique.

现有的解决方案都不适合我。可能我的情况比较特殊。

I have many UIButtonswithin a UIScrollView. When a UIButtonis pressed a new UIViewControlleris presented to the user. If a button is pressed and held long enough, the button will show its depressed state. My client was complaining that if you tap too quickly, no depressed state is shown.

UIButtons在一个UIScrollView. 当UIButton按下 a 时,UIViewController会向用户呈现一个新的。如果按钮被按下并保持足够长的时间,按钮将显示其按下状态。我的客户抱怨说,如果你敲得太快,就不会显示抑郁状态。

My solution: Inside the UIButtons' tap method, where I load the new UIViewControllerand present it on screen, I use

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

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

This schedules the loading of the next UIViewControlleron the next event loop. Allowing time for the UIButtonto redraw. The UIButtonnow shows its depressed state before loading the next UIViewController.

这安排了下UIViewController一个事件循环中下一个的加载。留出时间UIButton重新绘制。在UIButton现在显示加载下一个前的低迷状态UIViewController