轉眼六月份都快過去了,我發現這個月我一篇部落格都沒發表。表示很羞澀......
下個月很有可能會迎來部落格大爆發,只是部落格的主題有點......呃,留點懸念吧。
---------------------
有小夥伴和我反應說雖然看過我之前寫的那篇 delegate相關的文章,回過頭再看看ScrollView委託的實現過程還是不好理解。我趕緊找出之前那篇博文看了下......
尼瑪,這寫的都是些什麼東西,我自己都看得暈暈的......
做人要厚道!為了彌補了點,下面我就以一個新手的角度(其實自己就是新手)來研究下ScrollView的委託實現流程到底是怎樣的。
1、首先進入ScrollView.h檔案中,在聲明ScrollView這個類之前先聲明一個委託類,之所以稱之為委託,因為它的命名中包含 delegate 這個詞。如下:
class ScrollView; //前向聲明scrollViewclass ScrollViewDelegate{public: virtual ~ScrollViewDelegate() {} virtual void scrollViewDidScroll(ScrollView* view) = 0; virtual void scrollViewDidZoom(ScrollView* view) = 0;};
可以看到在這個委託類的聲明裡有兩個函數,一個是
scrollViewDidScroll(),這是當scrollView在被拖動時會響應該函數;另一個是
scrollViewDidZoom,我想應該是當scrollView在進行縮放時會響應該函數。
2、接下來就是聲明ScrollView這個類了。一開始我本能認為既然ScrollView要與ScrollViewDelegate這個類關聯起來,那麼它就應該繼承ScrollViewDelegate吧?可實際上並沒有,
ScrollView只是單純的繼承一個Layer罷了,如下:
class ScrollView : public Layer{};問題來了,
ScrollView既然與ScrollViewDelegate沒有“父子”關係,那麼它是如何調用ScrollViewDelegate中的那些函數的呢?我繼續看下ScrollView的類聲明。
發現有這麼兩個函數:
ScrollViewDelegate* getDelegate() { return _delegate; }void setDelegate(ScrollViewDelegate* pDelegate) { _delegate = pDelegate; }ScrollViewDelegate* _delegate;這裡比較容易理解,
先聲明一個ScrollViewDelegate* 類型的成員變數,然後通過setDelegate() 與 getDelegate()分別設定與擷取_delegate相應的對象。
看到這裡好像還不是很理解_delegate到底該怎麼用,那起碼有一些眉目了,畢竟ScrollViewDelegate已經浮出水面,不是那麼神秘。繼續往下看。
3、在ScrollView.cpp檔案中,我開始找下_delegate這個成員變數都在哪裡使用過。很快我在setContentOffset()這個函數中找到它的身影。
void ScrollView::setContentOffset(Point offset, bool animated/* = false*/){ if (animated) { //animate scrolling this->setContentOffsetInDuration(offset, BOUNCE_DURATION); } else { ...... if (_delegate != NULL) { _delegate->scrollViewDidScroll(this); //就是這裡。 } }}
setContentOffset()這個函數大家應該都很熟悉了,就是通過它來設定scrollView的位移的。我們從上面的代碼可以看到每當我們調用到setContentOffset()時,只要_delegate這個變數不為空白,那麼都會調用下面這行代碼:
_delegate->scrollViewDidScroll(this);
沒錯,
ScrollView就是在這裡調用到ScrollViewDelegate委託類中聲明的函數scrollViewDidScroll,它的參數 this 也就是ScrollView這個類所指向的對象啦,不用解釋。
知道了上面這些,接下來就好辦了,我們只要知道在ScrollView中哪裡有調用到setContentOffset() 這個函數就可以了。
4、我往下搜尋 setContentOffset 這個關鍵詞,發現有在好幾個地方調用到,其中最主要的還是在onTouchMoved()這個觸摸回呼函數中使用到。
onTouchMoved我也不用再多說了,每當我們觸控螢幕幕拖動時都會響應該函數,下面看下它的縮減版代碼:
void ScrollView::onTouchMoved(Touch* touch, Event* event){ if (!this->isVisible()) { return; } if (std::find(_touches.begin(), _touches.end(), touch) != _touches.end()) { if (_touches.size() == 1 && _dragging) { // scrolling ... if (frame.containsPoint(this->convertToWorldSpace(newPoint))) { ... this->setContentOffset(Point(newX, newY));//在這裡調用到 } } else if (_touches.size() == 2 && !_dragging) { const float len = _container->convertTouchToNodeSpace(_touches[0]).getDistance( _container->convertTouchToNodeSpace(_touches[1])); this->setZoomScale(this->getZoomScale()*len/_touchLength);//這裡是調用與縮放相關的函數 } }}
5、好了,說到這裡一切都已經開始變得清晰了,現在我先整理下髮型,然後做個總結。
首先在scrollView拖動過程中都會調用onTouchMoved()函數,然後再該函數中調用到到setContainOffset()這個函數,這個函數就是用來設定它的位移位置的;
在setContainOffset() 會調用到_delegate中的 scrollViewDidScroll()函數。
為什麼_delegate能有這麼大的權力調用ScrollViewDelegate中的函數呢?原因就在於它是ScrollViewDelegate聲明的,說直接點它就是ScrollViewDelegate的私生子!!!
6、下面我舉個例子吧。
我先聲明一個叫CoolStar的類,
class CoolStar : public Layer,public ScrollViewDelegate{public:...bool init();CREATE_FUNC(CoolStar);...//scroll 委託void scrollViewDidScroll(MyScrollView* view);void scrollViewDidZoom(MyScrollView* view);}CoolStar為什麼要繼承ScrollViewDelegate呢?別急,往下看init()函數的定義。bool CoolStar::init(){auto scroll_layer = Layer::create();...auto m_scroll = ScrollView::create(Size(...),scroll_layer);m_scroll->setDelegate(this);//看這裡!!!return true;}
上面我建立了一個scrollView,然後設定scrollView的委託指向當前類的對象,也就是this(看注釋的地方)
而我們知道setDelegate()這個函數是有參數的,它的參數是一個指向ScrollViewDelegate委託類的指標, 如下:
void setDelegate(ScrollViewDelegate* pDelegate);
這就要求我們建立ScrollView的這個類必須是繼承與ScrollViewDelegate,否則你就無法如此洒脫的執行下面這步了:
m_scroll->setDelegate(this);
恩,現在應該知道為什麼CoolStar這個類為什麼要繼承與ScrollViewDelegate委託類了吧。
接下來定義兩個scrollView的委託函數:
void CoolStar::scrollViewDidScroll(MyScrollView* view){CCLOG("star is so cool");}void CoolStar::scrollViewDidZoom(MyScrollView* view){}
運行程式,發現每次拖動scrollView時控制台都會輸出 "star is so cool"這串字串。
尊重原創,轉載請註明來源:http://blog.csdn.net/star530/article/details/34140469