UIScrollView有一個(gè)BOOL類(lèi)型的tracking屬性,用來(lái)返回用戶(hù)是否已經(jīng)觸及內(nèi)容并打算開(kāi)始滾動(dòng),我們從這個(gè)屬性開(kāi)始探究UIScrollView的工作原理:
當(dāng)手指觸摸到UIScrollView內(nèi)容的一瞬間,會(huì)產(chǎn)生下面的動(dòng)作:
攔截觸摸事件
tracking屬性變?yōu)閅ES
一個(gè)內(nèi)置的計(jì)時(shí)器開(kāi)始生效,用來(lái)監(jiān)控在極短的事件間隔內(nèi)是否發(fā)生了手指移動(dòng)
case1:當(dāng)檢測(cè)到時(shí)間間隔內(nèi)手指發(fā)生了移動(dòng),UIScrollView自己觸發(fā)滾動(dòng),tracking屬性變?yōu)镹O,手指觸摸下即使有(可以響應(yīng)觸摸事件的)內(nèi)部控件也不會(huì)再響應(yīng)觸摸事件。
case2:當(dāng)檢測(cè)到時(shí)間間隔內(nèi)手指沒(méi)有移動(dòng),tracking屬性保持YES,手指觸摸下如果有(可以響應(yīng)觸摸事件的)內(nèi)部控件,則將觸摸事件傳遞給控件進(jìn)行處理。
有很多新聞?lì)惖腁pp頂部都有一個(gè)滑動(dòng)菜單欄,主要模型可能是由一個(gè)UIScrollView包含多個(gè)UIButton控件組成;當(dāng)你操作的時(shí)候,手指如果是很迅速的在上面劃過(guò),會(huì)發(fā)現(xiàn)即使手指觸摸的地方有UIButton,但是并沒(méi)有觸發(fā)該UIButton的任何觸摸事件,這就是上面提到的case1;當(dāng)你手指是緩慢劃過(guò)或根本就沒(méi)動(dòng),才會(huì)觸發(fā)UIButton的觸摸事件,這是case2的情況。
上面的工作原理其實(shí)有一個(gè)屬性開(kāi)關(guān)來(lái)控制:delaysContentTouches。默認(rèn)值為YES;如果設(shè)置為NO,則無(wú)論手指移動(dòng)的多么快,始終都會(huì)將觸摸事件傳遞給內(nèi)部控件;設(shè)置為NO可能會(huì)影響到UIScrollView的滾動(dòng)功能。
再看另一個(gè)BOOL類(lèi)型的屬性canCencelContentTouches,從字面上理解是“可以取消內(nèi)容觸摸“,默認(rèn)值為YES。文檔里的解釋是這樣的:
A Boolean value that controls whether touches in the content view always lead to tracking.
If the value of this property is YES and a view in the content has begun tracking a finger touching it, and if the user drags the finger enough to initiate a scroll, the view receives a touchesCancelled:withEvent: message and the scroll view handles the touch as a scroll. If the value of this property is NO, the scroll view does not scroll regardless of finger movement once the content view starts tracking.
翻譯為中文大致如下:
這個(gè)BOOL類(lèi)型的值控制content view里的觸摸是否總能引發(fā)跟蹤(tracking)
如果屬性值為YES并且跟蹤到手指正觸摸到一個(gè)內(nèi)容控件,這時(shí)如果用戶(hù)拖動(dòng)手指的距離足夠產(chǎn)生滾動(dòng),那么內(nèi)容控件將收到一個(gè)touchesCancelled:withEvent:消息,而scroll view將這次觸摸作為滾動(dòng)來(lái)處理。如果值為NO,一旦content view開(kāi)始跟蹤(tracking==YES),則無(wú)論手指是否移動(dòng),scrollView都不會(huì)滾動(dòng)。
簡(jiǎn)單通俗點(diǎn)說(shuō),如果為YES,就會(huì)等待用戶(hù)下一步動(dòng)作,如果用戶(hù)移動(dòng)手指到一定距離,就會(huì)把這個(gè)操作作為滾動(dòng)來(lái)處理并開(kāi)始滾動(dòng),同時(shí)發(fā)送一個(gè)touchesCancelled:withEvent:消息給內(nèi)容控件,由控件自行處理。如果為NO,就不會(huì)等待用戶(hù)下一步動(dòng)作,并始終不會(huì)觸發(fā)scrollView的滾動(dòng)了。