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
当我触摸视图B
、touchesBegan: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
ios: uiscrollview 和 uiview 自动布局