1兰珍、首先進(jìn)入ScrollView.h文件中温亲,在聲明ScrollView這個(gè)類之前先聲明一個(gè)委托類,之所以稱之為委托匕得,因?yàn)樗拿邪?delegate 這個(gè)詞熄守。如下:
class ScrollView; //前向聲明scrollView
class ScrollViewDelegate
{
public:
virtual ~ScrollViewDelegate() {}
virtual void scrollViewDidScroll(ScrollView* view) = 0;
virtual void scrollViewDidZoom(ScrollView* view) = 0;
};
可以看到在這個(gè)委托類的聲明里有兩個(gè)函數(shù),一個(gè)是scrollViewDidScroll()耗跛,這是當(dāng)scrollView在被拖動(dòng)時(shí)會(huì)響應(yīng)該函數(shù);另一個(gè)是scrollViewDidZoom攒发,我想應(yīng)該是當(dāng)scrollView在進(jìn)行縮放時(shí)會(huì)響應(yīng)該函數(shù)调塌。
2、接下來(lái)就是聲明ScrollView這個(gè)類了惠猿。一開(kāi)始我本能認(rèn)為既然ScrollView要與ScrollViewDelegate這個(gè)類關(guān)聯(lián)起來(lái)羔砾,那么它就應(yīng)該繼承ScrollViewDelegate吧?可實(shí)際上并沒(méi)有偶妖,ScrollView只是單純的繼承一個(gè)Layer罷了姜凄,如下:
class ScrollView : public Layer{};
問(wèn)題來(lái)了,ScrollView既然與ScrollViewDelegate沒(méi)有“父子”關(guān)系趾访,那么它是如何調(diào)用ScrollViewDelegate中的那些函數(shù)的呢态秧?我繼續(xù)看下ScrollView的類聲明。
發(fā)現(xiàn)有這么兩個(gè)函數(shù):
ScrollViewDelegate* getDelegate() { return _delegate; }
void setDelegate(ScrollViewDelegate* pDelegate) { _delegate = pDelegate; }
ScrollViewDelegate* _delegate;
這里比較容易理解扼鞋,先聲明一個(gè)ScrollViewDelegate* 類型的成員變量申鱼,然后通過(guò)setDelegate() 與 getDelegate()分別設(shè)置與獲取_delegate相應(yīng)的對(duì)象愤诱。
看到這里好像還不是很理解_delegate到底該怎么用,那起碼有一些眉目了捐友,畢竟ScrollViewDelegate已經(jīng)浮出水面淫半,不是那么神秘。繼續(xù)往下看匣砖。
3科吭、在ScrollView.cpp文件中,我開(kāi)始找下_delegate這個(gè)成員變量都在哪里使用過(guò)猴鲫。很快我在setContentOffset()這個(gè)函數(shù)中找到它的身影对人。
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()這個(gè)函數(shù)大家應(yīng)該都很熟悉了变隔,就是通過(guò)它來(lái)設(shè)置scrollView的偏移的规伐。我們從上面的代碼可以看到每當(dāng)我們調(diào)用到setContentOffset()時(shí),只要_delegate這個(gè)變量不為空匣缘,那么都會(huì)調(diào)用下面這行代碼:
_delegate->scrollViewDidScroll(this);
沒(méi)錯(cuò)猖闪,ScrollView就是在這里調(diào)用到ScrollViewDelegate委托類中聲明的函數(shù)scrollViewDidScroll,它的參數(shù) this 也就是ScrollView這個(gè)類所指向的對(duì)象啦肌厨,不用解釋培慌。
知道了上面這些,接下來(lái)就好辦了柑爸,我們只要知道在ScrollView中哪里有調(diào)用到setContentOffset() 這個(gè)函數(shù)就可以了吵护。
4、我往下搜索 setContentOffset 這個(gè)關(guān)鍵詞表鳍,發(fā)現(xiàn)有在好幾個(gè)地方調(diào)用到馅而,其中最主要的還是在onTouchMoved()這個(gè)觸摸回調(diào)函數(shù)中使用到。
onTouchMoved我也不用再多說(shuō)了譬圣,每當(dāng)我們觸摸屏幕拖動(dòng)時(shí)都會(huì)響應(yīng)該函數(shù)瓮恭,下面看下它的縮減版代碼:
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));//在這里調(diào)用到
}
}
else if (_touches.size() == 2 && !_dragging)
{
const float len = _container->convertTouchToNodeSpace(_touches[0]).getDistance(
_container->convertTouchToNodeSpace(_touches[1]));
this->setZoomScale(this->getZoomScale()*len/_touchLength);//這里是調(diào)用與縮放相關(guān)的函數(shù)
}
}
}
5、好了厘熟,說(shuō)到這里一切都已經(jīng)開(kāi)始變得清晰了屯蹦,現(xiàn)在我先整理下發(fā)型,然后做個(gè)總結(jié)绳姨。
首先在scrollView拖動(dòng)過(guò)程中都會(huì)調(diào)用onTouchMoved()函數(shù)登澜,然后再該函數(shù)中調(diào)用到到setContainOffset()這個(gè)函數(shù),這個(gè)函數(shù)就是用來(lái)設(shè)置它的偏移位置的飘庄;
在setContainOffset() 會(huì)調(diào)用到_delegate中的 scrollViewDidScroll()函數(shù)脑蠕。
為什么_delegate能有這么大的權(quán)力調(diào)用ScrollViewDelegate中的函數(shù)呢?原因就在于它是ScrollViewDelegate聲明的跪削,說(shuō)直接點(diǎn)它就是ScrollViewDelegate的私生子?战肌7菡小!
6狞甚、下面我舉個(gè)例子吧锁摔。
我先聲明一個(gè)叫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()函數(shù)的定義谐腰。
bool CoolStar::init()
{
auto scroll_layer = Layer::create();
...
auto m_scroll = ScrollView::create(Size(...),scroll_layer);
m_scroll->setDelegate(this);//看這里!I堋十气!
return true;
}
上面我創(chuàng)建了一個(gè)scrollView,然后設(shè)置scrollView的委托指向當(dāng)前類的對(duì)象春霍,也就是this(看注釋的地方)
而我們知道setDelegate()這個(gè)函數(shù)是有參數(shù)的砸西,它的參數(shù)是一個(gè)指向ScrollViewDelegate委托類的指針, 如下:
void setDelegate(ScrollViewDelegate* pDelegate)址儒;
恩芹枷,現(xiàn)在應(yīng)該知道為什么CoolStar這個(gè)類為什么要繼承與ScrollViewDelegate委托類了吧。
接下來(lái)定義兩個(gè)scrollView的委托函數(shù):
void CoolStar::scrollViewDidScroll(MyScrollView* view)
{
CCLOG("star is so cool");
}
void CoolStar::scrollViewDidZoom(MyScrollView* view)
{
}
運(yùn)行程序莲趣,發(fā)現(xiàn)每次拖動(dòng)scrollView時(shí)控制臺(tái)都會(huì)輸出 "star is so cool"這串字符串鸳慈。
尊重原創(chuàng),轉(zhuǎn)載請(qǐng)注明來(lái)源:http://blog.csdn.net/star530/article/details/34140469