iOS多手势冲突问题

iOS多手势冲突问题,第1张

首先要搞清楚手势的几个BOOL值和代理方法

假如现在有个tableView加在scrollView上,需求让scrollView滚动到一定位置后在响应table的滚动事件,如下图:

首先,手势默认是互斥的,由事件的响应链可知,如果当前事件有被处理,那么事件将不会继续向上传递,意味着如果滑动tableView,父试图scrollView是不会响应的,显然就不是我们想要的。所以首先就需支持多手势

然后就是一些细节处理,在scrollView的代理方法里边设置边界值,进行简单的逻辑处理,滑动到某一个值就停下来

这里只是简单的一个demo,对手势冲突的一个简单处理,欢迎讨论。
附上 Demo

这是在安卓上触发的,这是一个问题,因为我已经有了jQuery touchstart,touchend等事件,它们在iOS上工作得很好(也在安卓上触发)。在Android上,当触摸和点击事件都处于活动状态时,我点击元素,它就会显示出来,然后立即隐藏起来,再次点击就什么也不做了。但是,如果我注释掉click事件代码,它在Android上工作得很好。问题是,它需要在台式机上工作。我试过移除触摸事件,但在iOS上点击不起作用。我还尝试用单击事件替换mousedown,但没有任何更改。如何解决此问题?
下面是我的完整jQuery:
function handleOverlayInteraction() {
$('mosaic-wrapper')on('mouseenter', function () {
$('#ddTestOverlay')show();
})on('mouseleave', function () {
$('#ddTestOverlay')hide();
});
var dragged = false;
$('mosaic-wrapper')on('touchstart', function () {
dragging = false;
});
$('mosaic-wrapper')on('touchmove', function () {
dragging = true;
});
$('mosaic-wrapper')on('touchend', function () {
if (dragging) {
return;
}
// Mobile single tap only
$('#ddTestOverlay')toggle();
});
$('#ddTestOverlay')on('click', function () {
$('#ddTestOverlay')toggle();
});
};
复制
浏览 47关注 0得票数 0
原文
1 个回答
高票数
*** 作
Paul已采纳
回答于2020-04-17
得票数 0
最后,我添加了一个clicked布尔变量,并在移动设备上单击时将其设置为true,然后在单击事件中检查它。基本上,触摸事件会在Android上触发,而click事件不会,但它仍然可以在桌面上工作,因为触摸事件不会在桌面上触发。更新的jQuery:
function handleOverlayInteraction() {
$('mosaic-wrapper')on('mouseenter', function () {
$('#ddTestOverlay')show();
})on('mouseleave', function () {
$('#ddTestOverlay')hide();
});
var dragged = false;
var clicked = false;
$('mosaic-wrapper')on('touchstart', function () {
dragging = false;
});
$('mosaic-wrapper')on('touchmove', function () {
dragging = true;
});
$('mosaic-wrapper')on('touchend', function (e) {
if (dragging) {
return;
}
// Mobile single tap only
clicked = true;
$('#ddTestOverlay')toggle();
});
$('#ddTestOverlay')on('click', function (e) {
if (clicked) return;
$('#ddTestOverlay')toggle();
});
};

1、在tableView上添加手势,并设置手势代理为当前控制器
2、利用代理方法- (BOOL)gestureRecognizer:(UIGestureRecognizer )gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer )otherGestureRecognizer 允许tableView上响应多手势
3、利用代理方法- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer )gestureRecognizer,控制添加的手势是否响应

通常在tableView上添加手势,会有冲突,比如在tableView上添加pan手势,就会让tableView的无法滚动,在tableViewCell上添加tap手势,就会让tableViewCell的didSelectCell方法无法响应等等,利用代理方法 gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 虽然能让添加的手势和原来的事件都响应,但是会造成一次性响应多个事件,这时候就需要用代理方法gestureRecognizerShouldBegin:来控制,添加的手势是否需要响应,并且不会阻断事件传递,这样就能很好的解决冲突问题。

您好,如果父视图使用了touchbegin方法,而子视图也同样使用了这个方法,那么建议您设置代理,委托方为子视图,代理方为父视图,协议中方法由父视图实现,这样点击子视图就会执行父视图的touchbegin方法完成响应

AutoLayout使用起来方便快捷,但是当我们的约束设置出现冲突的时候就是非常蛋疼的时候了,下面说说我解决约束冲突的经验。

好吧,现在我们的约束出现问题了,问题出现的原因本质上使我们约束设置的不够完美:1,设置了多余的约束;2,约束的设置没有考虑到界面尺寸的变化;3,前两条都有。

好吧,工程开始报警告了如下:

正常情况下,这样的段落会重复出现多次,看着就蛋疼,让我们来认真分析一下这个log到底想给我们传达什么信息吧。

先看前面的说明 

意思是,你的约束设置傻逼了,不拉不拉,你可以这样做:1,一个一个的看你的约束,看看那个跟你想要的不一样;2,找到并修改它。   这两句简直没有一点卵用,谁不知道找到并修改它,关键是怎么找啊,也不给个提示,真是醉了,好吧自己研究吧,我们接着看小括号里面的冲突约束吧,先看第一句

我来凭借我多年经验翻译一下吧:约束:0x13823a560  V:我猜测这里是 vertical 也就是竖直的意思,相应的H就是水平的意思 , "|" 是一个替代符号表示后面的小括号里面的 字典中的内容也就是 内存地址为0x13823920f的UITableViewContentView,|-(0)-[UIView:0x138239490] 就是|到后面这个view 的竖直距离为0 。整句话下来意思就是:地址为0x13823920f的UITableViewContentView 距离 内存地址为0x138239490的UIView 的竖直距离为0的内存地址为0x13823a560约束。整句话修饰的是一个名词。

同理,第二句的意思是:UITableviewCellContentView 到这个lab 的竖直距离为5的约束;第三句的意思:这个UIView倒这个UIlabel 的竖直距离为5;第四句没有V了,并且只涉及到一个控件:UITableviewCellContentView 自身的高度。  根据内存地址我们可以看出总共涉及到了一个view 、一个contentView、一个label三个控件。 然后下面是被破坏的约束:UIView 到 UILabel的竖直距离为5。也就是说,这个约束在运行的时候因为 父视图(UITableviewCellContentView)尺寸的改变不能正常约束控件了。

了解了他这个意思,我们可以从我们的Storyboard 或者Xib文件中寻找出问题的 约束了,怎么找呢,我们可以找关键点,从最后一个被破坏的约束找起,竖直距离为5;而且是 label 跟UIView的,想必不会 有太多,如果有太多可以修改几个排除一下,然后再试着调整一下父视图的size,基本上就能确定我们不合理的约束所在了,不过这个过程仍然是比较麻烦的,因为约束冲突本身就是一件蛋疼的事。

找到了产生冲突的约束之后,设置约束的优先级也是一种很方便解决办法,感谢AmySong同学的提议。

才学尚浅,不足之处欢迎与我理论、探讨。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13086933.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-30
下一篇 2023-05-30

发表评论

登录后才能评论

评论列表(0条)

保存