简体   繁体   English

为什么touchesBegan,target-action和touchesEnded的执行顺序会随着UIButton的快速触摸而改变?

[英]Why does the execution order of touchesBegan, target-action and touchesEnded change with fast touches of UIButton?

UPDATE: With the blush of shame I discovered that the order had nothing to do with the speed of tapping. 更新:羞愧的脸红,我发现顺序与攻丝速度无关。 I was calling the visual code before the super touchesEnded:withEvent call, which was why if you tapped really fast, the display never got a chance to draw the highlighted state before being dismissed again. 我在super touchesEnded:withEvent调用之前就调用了可视代码,这就是为什么如果您快速点按一下,则显示在再次被关闭之前就没有机会绘制突出显示的状态。 Because the code that was actually causing the main thread to block just a few milliseconds, the highlighted state would stay visible until the main thread unblocked again, where as if you tapped really fast, it looked like nothing happened at all. 因为实际上实际上导致主线程阻塞的代码只有几毫秒,所以突出显示的状态将保持可见,直到再次取消阻塞主线程为止,就像您真正快速地点击了它一样,看起来什么也没有发生。 Moving the super call up to the top of the overridden method fixed it all. 将超级调用移至覆盖方法的顶部即可解决所有问题。 Sorry, if any moderator sees this post it can be deleted. 抱歉,如果有任何主持人看到此信息,可以将其删除。 shame 耻辱

This problem must have been asked a 1000 times at SO, yet I can't find the explanation to match my specific issue. 在SO上,这个问题一定被问过1000次,但是我找不到适合我具体问题的解释。

I have a UIButton subclass with a custom design. 我有一个自定义设计的UIButton子类。 Of course the design is custom enough that I can't just use the regular setSomething:forControlState: methods. 当然,设计足够自定义,我不能只使用常规的setSomething:forControlState:方法。 I need a different backgroundcolor on touch, for one, and some icons that need to flash. 我需要一个不同的背景色,例如一个,还有一些需要闪烁的图标。

To implement these view changes, I (counter-intuitively) put the display code in (A) touchesBegan:withEvent and (Z) touchesEnded:withEvent: , before calling their respective super methods. 为了实现这些视图更改,我(反直觉地)在调用它们各自的super方法之前,将显示代码放入(A) touchesBegan:withEvent和(Z) touchesEnded:withEvent: Feels weird, but it works as intended, or so it seemed at first. 感觉很奇怪,但是它按预期运行,或者乍一看似乎如此。

After implementing addTarget:action:forControlEvents was used to bind the UIControlEventTouchUpInside to the method (X) itemTapped: , I would expect these methods to always fire in the order (A)(X)(Z). 在实现addTarget:action:forControlEvents之后,将UIControlEventTouchUpInside绑定到方法(X) itemTapped:我希望这些方法总是按(A)(X)(Z)的顺序触发。 However, if you tap the screen real fast (or the mouse in simulator), they fire in the order (A)(Z)(X). 但是,如果您快速真正地点击屏幕(或模拟器中的鼠标),它们将按(A)(Z)(X)的顺序触发。 Where (A) and (Z) follow each other in such rapid succession, that the whole visual feedback for tapping is invisible. 其中(A)和(Z)以如此快速的顺序彼此跟随,从而看不见敲击的整个视觉反馈。 This is unwanted behavior. 这是不想要的行为。 This also can't be the way to go, for so many apps need similar behavior, right? 这也不可行,因为许多应用程序都需要类似的行为,对吗?

So my question to you is: What am I doing wrong? 所以我对你的问题是:我在做什么错? One thing I'm guessing is that the visual appearance of the buttons shouldn't be manipulated in the touchesBegan:withEvent and touchesEnded:withEvent , but then where? 我猜想的一件事是,不应在touchesBegan:withEventtouchesEnded:withEvent操纵按钮的视觉外观,但是在哪里呢? Or am I missing some other well known fact? 还是我错过了其他一些众所周知的事实?

Thanks for the nudge, Eric-Paul. 感谢您的推动,埃里克·保罗。

I don't know why the order is different, but here's 2 suggestions to help deal with it. 我不知道为什么顺序会有所不同,但是这里有2条建议可以帮助您处理。

What visual changes are you making to the button? 您对按钮进行了哪些视觉更改? If it's things like changing title/image/background image, you can do all this by modifying the highlighted state of the button. 如果要更改标题/图像/背景图像,则可以通过修改按钮的突出显示状态来完成所有这些操作。 You can set a few properties like title and background image per-state. 您可以按状态设置一些属性,例如标题和背景图像。 When the user's finger is down on the button, the highlighted state is turned on, so any changes you make to this state will be visible at this time. 当用户的手指放在按钮上时, highlighted状态将打开,因此您对此状态所做的任何更改都将在此时可见。 Do note that if you're making use of the selected state on the button, then you'll need to also set up the visual appearance for UIControlStateHighlighted|UIControlStateSelected , otherwise it will default back to inheriting from Normal when both highlighted & selected are on. 请注意,如果您正在使用按钮上的selected状态,则还需要设置UIControlStateHighlighted|UIControlStateSelected的视觉外观,否则当选中突出显示和选中状态时,它将默认恢复为从Normal继承。 。

The other suggestion is to ditch touchesBegan:withEvent: and touchesEnded:withEvent: and switch over to using the methods inherited from UIControl, namely beginTrackingWithTouch:withEvent: and endTrackingWithTouch:withEvent: . 另一个建议是touchesEnded:withEvent: touchesBegan:withEvent:touchesEnded:withEvent:并切换到使用从UIControl继承的方法,即beginTrackingWithTouch:withEvent:endTrackingWithTouch:withEvent: You may also want to implement continueTrackingWithTouch:withEvent: and use the touchInside property to turn off your visual tweaks if the touch leaves the control. 您可能还想实现continueTrackingWithTouch:withEvent: touchInside并在触摸离开控件时使用touchInside属性关闭视觉调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM