>用户将手指从屏幕上抬起.这会触发一个UItouchEvent,阶段Ended,它会调用一些回调方法.
问题:此回调方法的内容和位置是什么?它不在controllerA中,它不在controllerB中.据我所知,这不是任何观点.但它存在.
解决方法 澄清一下,这是发生了什么(根据@switz):>响应-touchesBegan:withEvent:,显示视图控制器
通过segue模态地
>当用户抬起手指时,应取消视图控制器.
问题是如何对提起的手指做出反应,因为
-touchesEnded:withEvent:未被调用.
简短的回答是呈现的视图控制器需要使用“Over Full”
屏幕“modalPresentationStyle而不是默认的”全屏“样式
(这可以指定为segue的表示样式,或者如果
这是“默认”然后是呈现的视图控制器的呈现样式.
长答案需要简要概述触摸处理的工作原理.这个
解释忽略了手势识别器:
当触摸开始时,它被传递到包含该触摸的“最顶层”视图
接触点.从那里它被传递到响应链直到一些
对象决定处理触摸(通过实现表示
-touchesBegan:withEvent:而不是调用super).
对触摸的后续更改(例如,移动,结束,取消)将被传回
接受触摸的同一观点.该观点将继续收到
触摸事件直到触摸完成或取消.
当应用程序移动到后台时触摸会被取消(因为
例如打来电话),或者像UIScrollVIEw这样的UIKit类决定
它需要接管触摸处理(因为手指移动得足够远)
它看起来像用户想要滚动).这里还有一些有趣的东西
使用UIScrollVIEw.delaysContenttouches,但可以忽略.
但是有一种皱纹,没有记录的东西:只接触交付
只要视图与窗口保持关联,就会发生这种情况.如果认为那个
被认为是“最顶层”(与UItouch相关的视图)是
从窗口移开,然后触摸被认为已经消失,
重要的是,没有任何事件可以再发送给任何人.这是
即使有问题的视图不是处理触摸的对象,也是如此.
最后的皱纹是造成这个问题的原因.因为默认
“全屏”演示风格实际上删除了旧视图控制器
从窗口查看,触摸处理立即停止.但是,“结束了
全屏“演示风格不会删除它,它只是掩盖了旧的
查看与一个. “全屏幕”通常在呈现视图时使用
控制器不是完全不透明的,但在这种情况下我们正在使用它,所以触摸
处理不会中断.
但那还不是全部.这里还有另一个问题,那就是当时的观点
被触摸的生活在一个UIScrollVIEw(一个可滚动或
总是反d).在这种情况下,即使使用“全屏幕”,您也会发现,
触摸事件继续传递,手指移动一下
突然导致触摸被取消.这是因为UIScrollVIEw
不知道它已被掩盖,并已决定用户实际上正在尝试
滚动.这导致它取消触摸.
不过,有一个解决方案.这有点难看,但解决办法是
执行时立即取消任何封闭滚动视图上的任何滚动
塞古.这可以使用以下代码完成:
class VIEwController: UIVIEwController { // this is called from -touchesBegan:withEvent: from a child vIEw // the child vIEw is `sender` func touchDown(sender: UIVIEw) { var vIEw = sender.supervIEw while vIEw != nil { if let scrollVIEw = vIEw as? UIScrollVIEw { // toggle the panGestureRecognizer enabled state to immediately // cause it to fail. let enabled = scrollVIEw.panGestureRecognizer.enabled scrollVIEw.panGestureRecognizer.enabled = true scrollVIEw.panGestureRecognizer.enabled = enabled } vIEw = vIEw?.supervIEw } performSegueWithIDentifIEr(IDentifIEr,sender: self) } // ...}
当然,没有手势就不能完成触摸处理的讨论
识别器.手势识别器几乎可以改变触摸的一切
处理.他们可以在任何触摸上获得第一个dib,并且可以中断视图触摸
随时处理.例如,UIScrollVIEw的UIPanGestureRecognizer
是什么用于滚动,当它进入“开始”状态(因为
用户已经移动了足够的手指),这就是导致触摸的原因
取消.
所以,鉴于此,这里真正最好的解决方案是不实施
-touchesBegan:withEvent:at,但要使用手势识别器.最简单的
这里的解决方案是使用UILongPressGestureRecognizer
minimumPressDuration设置为0,allowableMovement设置为some
可笑的高价值(因为你不希望运动取消触摸).我
因为UILongPressGestureRecognizer是连续的,所以推荐这个
识别器,意味着它将为Began,Moved和Ended发送事件
建议的设置,它将发送它们以响应触摸开始,
移动,结束.更重要的是,一旦你的识别器开始处理触摸,
这会自动阻止任何其他识别器(例如滚动视图的平移
识别器)从“接管”和取消触摸.
请注意,如果您将手势识别器附加到scrollVIEw本身
(例如UItableVIEw)但只想响应某些位置的触摸
(例如在一行上),那么你需要限制识别器.你可以使用
委托方法gestureRecognizer(_:shouldReceivetouch :)来做这件事
像这样:
func gestureRecognizer(recognizer: UIGestureRecognizer,shouldReceivetouch touch: UItouch) -> Bool { // if you might be the delegate of multiple recognizers,check for that // here. This code will assume `recognizer` is the correct recognizer. // We're also assuming,for the purposes of this code,that we're a // UItableVIEwController and want to only capture touches on rows in the // first section. let touchLocation = touch.locationInVIEw(self.tableVIEw) if let indexPath = self.tableVIEw.indexPathForRowAtPoint(touchLocation) { if indexPath.section == 0 { // we're on one of the special rows return true } } return false}
这样识别器不会阻止tableVIEw的panGestureRecognizer当用户触摸桌子上的其他地方时滚动.
总结以上是内存溢出为你收集整理的iOS:检测触摸,触发,修饰全部内容,希望文章能够帮你解决iOS:检测触摸,触发,修饰所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)