iOS:检测触摸,触发,修饰

iOS:检测触摸,触发,修饰,第1张

概述>用户将手指放在屏幕上.这会触发一个UITouchEvent,阶段Began,它调用controllerA中的touchesBegan:withEvent:方法,该方法执行从controllerA到controllerB的segue. >用户将手指从屏幕上抬起.这会触发一个UITouchEvent,阶段Ended,它会调用一些回调方法. 问题:此回调方法的内容和位置是什么?它不在controlle >用户将手指放在屏幕上.这会触发一个UItouchEvent,阶段Began,它调用controllerA中的touchesBegan:withEvent:方法,该方法执行从controllerA到controllerB的segue.
>用户将手指从屏幕上抬起.这会触发一个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:检测触摸,触发,修饰所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

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

原文地址: https://outofmemory.cn/web/1113883.html

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

发表评论

登录后才能评论

评论列表(0条)

保存