Cocos2dx 小技巧(十五)話說(shuō)ScrollView的delegate實(shí)現(xiàn)過(guò)程


樸實(shí)的埃菲爾

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末喧伞,一起剝皮案震驚了整個(gè)濱河市走芋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌潘鲫,老刑警劉巖翁逞,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異溉仑,居然都是意外死亡熄攘,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門彼念,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人浅萧,你說(shuō)我怎么就攤上這事逐沙。” “怎么了洼畅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵吩案,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我帝簇,道長(zhǎng)徘郭,這世上最難降的妖魔是什么靠益? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮残揉,結(jié)果婚禮上胧后,老公的妹妹穿的比我還像新娘。我一直安慰自己抱环,他們只是感情好壳快,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著镇草,像睡著了一般眶痰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上梯啤,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天竖伯,我揣著相機(jī)與錄音,去河邊找鬼因宇。 笑死七婴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的羽嫡。 我是一名探鬼主播本姥,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼杭棵!你這毒婦竟也來(lái)了婚惫?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤魂爪,失蹤者是張志新(化名)和其女友劉穎先舷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體滓侍,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒋川,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撩笆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捺球。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖夕冲,靈堂內(nèi)的尸體忽然破棺而出氮兵,到底是詐尸還是另有隱情,我是刑警寧澤歹鱼,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布泣栈,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏南片。R本人自食惡果不足惜掺涛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望疼进。 院中可真熱鬧薪缆,春花似錦、人聲如沸颠悬。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赔癌。三九已至诞外,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間灾票,已是汗流浹背峡谊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刊苍,地道東北人既们。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像正什,于是被迫代替她去往敵國(guó)和親啥纸。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一.UITextField屬性 0.enablesReturnKeyAutomatically 默認(rèn)為No,如果設(shè)...
    奮斗ing0310閱讀 1,644評(píng)論 0 2
  • 前言 人生苦多婴氮,快來(lái) Kotlin 斯棒,快速學(xué)習(xí)Kotlin! 什么是Kotlin主经? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,211評(píng)論 9 118
  • *面試心聲:其實(shí)這些題本人都沒(méi)怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來(lái)就是把...
    Dove_iOS閱讀 27,150評(píng)論 30 470
  • *7月8日上午 N:Block :跟一個(gè)函數(shù)塊差不多荣暮,會(huì)對(duì)里面所有的內(nèi)容的引用計(jì)數(shù)+1,想要解決就用__block...
    炙冰閱讀 2,488評(píng)論 1 14
  • “成為一個(gè)作家”罩驻,覺(jué)得自己是個(gè)老男孩了穗酥,可還是產(chǎn)生了這樣的想法。就像以前一樣惠遏,我記得寫過(guò)兩篇完整的短篇小說(shuō)砾跃,一篇是...
    與落霞齊飛閱讀 177評(píng)論 3 1