UIScrollView 和 touchesBegan / touchesEnded 等

Posted

技术标签:

【中文标题】UIScrollView 和 touchesBegan / touchesEnded 等【英文标题】:UIScrollView and touchesBegan / touchesEnded etc 【发布时间】:2015-03-05 08:49:31 【问题描述】:

我有一个带有 2 个子视图的 UIView,我们称之为视图 A

一个基本的UIView,称为B 一个UIScrollView,叫C

我在视图A中重写了以下方法:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

当我触摸视图BtouchesBegan:withEvent:touchesEnded:withEvent: 时,会被调用,但如果我触摸UIScrollView(视图C),则不会调用。

我知道这是预期的行为,但我试图了解原因。我找不到任何明确的答案。有什么想法吗?

【问题讨论】:

视图 C 在布局方面是否在视图 B 之下?你会在被覆盖的方法中调用超级方法吗? B 和 C 不重叠。是的,我称之为超级方法。 ***.com/a/25108078/1702413 @TonyMkenu :我不想禁用 UIScrollView 上的用户交互 【参考方案1】:

使用 TapGestureRecognizer 代替 touchBegan 方法

UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
singleTapGestureRecognizer.numberOfTapsRequired = 1;
singleTapGestureRecognizer.enabled = YES;
singleTapGestureRecognizer.cancelsTouchesInView = NO;
[scrollView addGestureRecognizer:singleTapGestureRecognizer];

- (void)singleTap:(UITapGestureRecognizer *)gesture   
//handle taps   

斯威夫特版本:

let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: "singleTap:")
    singleTapGestureRecognizer.numberOfTapsRequired = 1
    singleTapGestureRecognizer.enabled = true
    singleTapGestureRecognizer.cancelsTouchesInView = false
    scrollViewH.addGestureRecognizer(singleTapGestureRecognizer)

func singleTap(sender: UITapGestureRecognizer) 
    println("handle taps ")


【讨论】:

【参考方案2】:

如果您有滚动视图,thouchesBegan 方法将不起作用,因为如果要滚动,您必须在情节提要中将 userInteractionEnabled 启用为 YES。如果您将其设置为“否”,它将触发。所以解决方案是使用 TapGestureRecognizer 将此添加到您的 viewDidLoad:

let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: "MyTapMethod:")
    singleTapGestureRecognizer.numberOfTapsRequired = 1
    singleTapGestureRecognizer.enabled = true
    singleTapGestureRecognizer.cancelsTouchesInView = false
    myscrollView.addGestureRecognizer(singleTapGestureRecognizer)

然后在你的控制器中添加这个 MyTapMethod。

func MyTapMethod(sender: UITapGestureRecognizer) 
        //NSLog("touchesBegan")
        self.view.endEditing(true)
    

这工作正常。

【讨论】:

【参考方案3】:

您至少有 2 个选项:

1) “通过将 userInteractionEnabled 设置为 NO 以获取滚动视图”。 更多信息在这里https://***.com/a/25108078/1702413

2) 子类化您的 UIScrollView - 例如使用 https://dl.dropboxusercontent.com/u/19438780/ClassScrollViewDelegate.zip

更新

为什么?请再次阅读文档:

“因为滚动..它必须知道触摸是否表示意图 滚动...它暂时拦截一个触地事件... .. 滚动视图取消子视图中的任何跟踪并执行 滚动自身”

最重要的是: **

子类可以覆盖 touchesShouldBegin:withEvent:inContentView:、pagingEnabled 和 touchesShouldCancelInContentView:方法

从这里:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIScrollView_Class/index.html#//apple_ref/doc/uid/TP40006922

【讨论】:

我不是在寻找解决方案,我想了解为什么在我触摸 UIScrollView 时不调用 touchesBegan【参考方案4】:

Swift 3/4 版本:

let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MyViewController.tapRecognized))
singleTapGestureRecognizer.numberOfTapsRequired = 1
singleTapGestureRecognizer.isEnabled = true
singleTapGestureRecognizer.cancelsTouchesInView = false
scrollView.addGestureRecognizer(singleTapGestureRecognizer)

然后:

@objc func tapRecognized() 
    view.endEditing(true)

【讨论】:

【参考方案5】:

请勾选此项以使用滚动视图的平移手势识别触摸事件(开始、移动、结束),

Class CustomScrollView:UIScrollView


CustomScrollView()


 (this.GestureRecognizers[1] as UIPanGestureRecognizer).AddTarget(() => this.PanHandle(this.GestureRecognizers[1] as UIPanGestureRecognizer));
    




 private void PanHandle(UIPanGestureRecognizer gestureRecognizer)
          
  
  var touchLocation=gestureRecognizer.LocationInView(this)
    
       

  if (gestureRecognizer.State == UIGestureRecognizerState.Began)
            
    
             
      //Touches began
             
   
     
else if (gestureRecognizer.State == UIGestureRecognizerState.Changed)
            
   
           
        //Touches Moved
             
   
               
 else if (gestureRecognizer.State == UIGestureRecognizerState.Ended)
         
       
             
       //Touches ended
              
  
           
 

    

Regards,
Ashwin

【讨论】:

以上是关于UIScrollView 和 touchesBegan / touchesEnded 等的主要内容,如果未能解决你的问题,请参考以下文章

UIScrollView 嵌入其他 UIScrollView

UIScrollView

UIScrollView 内 UIScrollView 内 UIScrollView

ios: uiscrollview 和 uiview 自动布局

如何使在Swift中使用UIScrollView进行滚动和缩放

UICollectionViewCell 和 UIScrollView