子类 UIScrollView 检测按钮内的触摸,但对用户交互无响应

Posted

技术标签:

【中文标题】子类 UIScrollView 检测按钮内的触摸,但对用户交互无响应【英文标题】:Subclassed UIScrollView detects touches within buttons but is otherwise unresponsive to user interaction 【发布时间】:2016-03-25 17:05:25 【问题描述】:

我有一个垂直的 UIScrollView,它有几个大按钮占据了滚动视图中的大部分空间。出于这个原因,我不得不继承这篇文章ios 8 - buttons in horizontal scroll view intercepting pan event - scroll does not work) 之后的滚动视图并覆盖以下类方法:

- (BOOL)touchesShouldBegin:(NSSet *)touches withEvent:(UIEvent *)event inContentView:(UIView *)view

    static int count = 0;
    count++;
    NSLog(@"calling this function 2");
    NSLog(@"count = %d", count);
    UITouch *touch = [touches anyObject];

    if(touch.phase == UITouchPhaseMoved)
    
        NSLog(@"UITouchPhaseMoved so returning no");
        return NO;
    


    else
    
        NSLog(@"returning super");
        NSLog(@"returning whatever this value is %d 0/1", [super touchesShouldBegin:touches withEvent:event inContentView:view]);
        [super touchesShouldBegin:touches withEvent:event inContentView:view];
        return [super touchesShouldBegin:touches withEvent:event inContentView:view];
    

当我运行我的应用程序时,点击按钮时会调用上述函数,但当我在滚动视图中拖动按钮内部或外部的任何位置时不会调用该函数。而且无论我尝试拖动到哪里,滚动视图都不会滚动。

这是我所有与滚动视图相关的代码(它是用 IB 设置的):

            smallView.scrollEnabled = YES;
            smallView.contentSize = CGSizeMake(smallView.frame.size.width, smallView.frame.size.height*1.4);
            smallView.delegate = self;

这里是按钮相关的代码,以防万一:

NSArray *buttonsArray = @[button1, button2, button3, button4, button5];
for (int i = 0; i < [buttonsArray count]; i++) 
    UIButton *button = buttonsArray[i];
    button.tag = i+1;
    [button addTarget:self action:@selector(p_motivationButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
    button.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
    button.titleLabel.textAlignment = NSTextAlignmentCenter;

为什么我的滚动视图没有滚动,甚至没有调用touchesShouldBegin

【问题讨论】:

你在 touchphase 移动时返回 no 吗? @TejaNandamuri 我不知道,这可以改变,但函数永远不会进入逻辑的那个分支。 你在哪里实现了触摸移动方法? touches begin 方法无法拦截touched 移动事件。它只会检测触摸事件的起点。 请看第五段developer.apple.com/library/ios/documentation/UIKit/Reference/…: 它解释了为什么滚动事件没有发送到子视图。 【参考方案1】:

子类UIScrollView 并覆盖touchesShouldCancelInContentView(),如下所示:

override func touchesShouldCancelInContentView(view: UIView) -> Bool 
    if let _ = view as? UIControl 
        return true
    
    else 
        return super.touchesShouldCancelInContentView(view)
    

【讨论】:

以上是关于子类 UIScrollView 检测按钮内的触摸,但对用户交互无响应的主要内容,如果未能解决你的问题,请参考以下文章

自定义按钮视图:检测触摸向下/向上,快速,并回退拖动到 UIScrollView

UiScrollview scrollviewDidScroll 检测用户触摸

acessoryView 内的 UITextField -- 清除按钮未检测到触摸

以 UIScrollView 作为子类的 UIView 不接收触摸事件

UIImageView 子类触摸检测

如何从 UIScrollView 内的 UIButton 传递延迟滚动手势?