問(wèn)題描述
我希望我的 UIScrollView 及其子視圖都能接收子視圖內(nèi)的所有觸摸事件.每個(gè)人都可以以自己的方式做出回應(yīng).
I want both my UIScrollView and its subviews to receive all touch events inside the subview. Each can respond in its own way.
或者,如果將點(diǎn)擊手勢(shì)轉(zhuǎn)發(fā)到子視圖,一切都會(huì)好起來(lái)的.
Alternatively, if tap gestures were forwarded to subviews, all would be well.
很多人都在這個(gè)一般領(lǐng)域苦苦掙扎.以下是眾多相關(guān)問(wèn)題中的幾個(gè):
A lot of people are struggling in this general area. Here are a few of the many related questions:
UIScrollView 如何從其子視圖中竊取觸摸
如何從 UIScrollView 竊取觸摸?
如何在 UIScrollView 中取消滾動(dòng)
順便說(shuō)一句,如果我在滾動(dòng)視圖中覆蓋 hitTest:withEvent:,只要 userInteractionEnabled 為 YES,我就會(huì)看到觸摸.但這并不能真正解決我的問(wèn)題,因?yàn)?
Incidentally, if I override hitTest:withEvent: in the scroll view, I do see the touches as long as userInteractionEnabled is YES. But that doesn't really solve my problem, because:
1) 到那時(shí),我不知道是不是水龍頭.
2) 有時(shí)我需要將 userInteractionEnabled 設(shè)置為 NO.
1) At that point, I don't know if it's a tap or not.
2) Sometimes I need to set userInteractionEnabled to NO.
為了澄清,是的,我想將水龍頭與平底鍋區(qū)別對(duì)待.點(diǎn)擊應(yīng)該由子視圖處理.平底鍋可以通過(guò)滾動(dòng)視圖以通常的方式處理.
To clarify, yes, I want to treat taps differently from pans. Taps should be handled by subviews. Pans can be handled by the scroll view in the usual way.
推薦答案
首先,免責(zé)聲明.如果在 UIScrollView
上將 userInteractionEnabled
設(shè)置為 NO
,則不會(huì)將觸摸事件傳遞給子視圖.據(jù)我所知,除了一個(gè)例外:在 UIScrollView
的父視圖上攔截觸摸事件,并將這些事件專門(mén)傳遞給 UIScrollView
.不過(guò),老實(shí)說(shuō),我不知道你為什么要這樣做.如果你想禁用特定的 UIScrollView 功能(比如......好吧,滾動(dòng)),你可以很容易地做到這一點(diǎn),而無(wú)需禁用 UserInteraction.
First, a disclaimer. If you set userInteractionEnabled
to NO
on the UIScrollView
, no touch events will be passed to the subviews. So far as I'm aware, there's no way around that with one exception: intercept touch events on the superview of the UIScrollView
, and specifically pass those events to the subviews of UIScrollView
. To be honest, though, I don't know why you would want to do this. If you're wanting to disable specific UIScrollView functionality (like...well, scrolling) you can do that easily enough without disabling UserInteraction.
如果我理解您的問(wèn)題,您需要 UIScrollView 處理點(diǎn)擊事件 并傳遞給子視圖嗎?無(wú)論如何(無(wú)論手勢(shì)是什么),我認(rèn)為您正在尋找的是協(xié)議方法 gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: 在協(xié)議 UIGestureRecognizerDelegate
中.在您的子視圖中,無(wú)論您擁有什么手勢(shì)識(shí)別器,都在手勢(shì)識(shí)別器上設(shè)置一個(gè)委托(可能是首先設(shè)置 UIGestureReconginzer
的任何類).覆蓋上述方法并返回 YES
.現(xiàn)在,該手勢(shì)將與任何其他可能竊取"該手勢(shì)的識(shí)別器一起被識(shí)別(在您的情況下,點(diǎn)擊).使用此方法,您甚至可以微調(diào)您的代碼以僅向子視圖發(fā)送某些類型的手勢(shì)或僅在某些情況下發(fā)送手勢(shì).它給了你很多控制權(quán).請(qǐng)務(wù)必閱讀該方法,尤其是這一部分:
If I understand your question, you need tap events to be processed by the UIScrollView and passed to the subviews? In any case (whatever the gesture is), I think what you're looking for is the protocol method gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: in the protocol UIGestureRecognizerDelegate
. In your subviews, whatever gesture recognizers you have, set a delegate (probably whatever class is setting the UIGestureReconginzer
in the first place) on the gesture recognizer. Override the above method and return YES
. Now, this gesture will be recognized along with any other recognizers that might have 'stolen' the gesture (in your case, a tap). Using this method you can even fine tune your code to only send certain kinds of gestures to the subviews or send the gesture only in certain situations. It gives you a lot of control. Just be sure to read about the method, especially this part:
識(shí)別手勢(shì)時(shí)調(diào)用該方法手勢(shì)識(shí)別器或其他手勢(shì)識(shí)別器會(huì)阻止其他手勢(shì)識(shí)別器識(shí)別其手勢(shì).注意返回 YES 保證允許同時(shí)識(shí)別;另一方面,返回 NO 并不能保證防止同時(shí)識(shí)別,因?yàn)槠渌謩?shì)識(shí)別器的委托可能會(huì)返回 YES.
This method is called when recognition of a gesture by either gestureRecognizer or otherGestureRecognizer would block the other gesture recognizer from recognizing its gesture. Note that returning YES is guaranteed to allow simultaneous recognition; returning NO, on the other hand, is not guaranteed to prevent simultaneous recognition because the other gesture recognizer's delegate may return YES.
當(dāng)然,有一點(diǎn)需要注意:這只適用于手勢(shì)識(shí)別器.因此,如果您嘗試使用 touchesBegan:
、touchesEnded
等來(lái)處理觸摸,您可能仍然會(huì)遇到問(wèn)題.當(dāng)然,您可以使用 hitTest:
將原始觸摸事件發(fā)送到子視圖,但為什么呢?當(dāng)您可以將 UIGestureRecognizer
附加到視圖并免費(fèi)獲得所有這些功能時(shí),為什么要使用 UIView
中的這些方法來(lái)處理事件?如果您需要以標(biāo)準(zhǔn) UIGestureRecognizer
無(wú)法提供的方式處理觸摸,subclass UIGestureRecognizer
并在那里處理觸摸.這樣您就可以獲得 UIGestureRecognizer
的所有功能以及您自己的自定義觸摸處理.我真的認(rèn)為 Apple 打算讓 UIGestureRecognizer
替換開(kāi)發(fā)人員在 UIView
上使用的大部分(如果不是全部)自定義觸摸處理代碼.它允許代碼重用,并且在減輕哪些代碼處理哪些觸摸事件時(shí)更容易處理.
Of course, there's a caveat: This only applies to gesture recognizers. So you may still have problems if you're trying to use touchesBegan:
, touchesEnded
, etc to process the touches. You can, of course, use hitTest:
to send raw touch events on to the subviews, but why? Why process the events using those methods in UIView
, when you can attach a UIGestureRecognizer
to a view and get all of that functionality for free? If you need touches processed in a way that no standard UIGestureRecognizer
can provide, subclass UIGestureRecognizer
and process the touches there. That way you get all the the functionality of a UIGestureRecognizer
along with your own custom touch processing. I really think Apple intended for UIGestureRecognizer
to replace most (if not all) of the custom touch processing code that developers use on UIView
. It allows for code-reuse and it's a lot easier to deal with when mitigating what code processes what touch event.
這篇關(guān)于允許 UIScrollView 及其子視圖都響應(yīng)觸摸的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!