iOS:如何復(fù)用兩個(gè)view實(shí)現(xiàn)可無限滾動(dòng)的全屏頁面

學(xué)iOS的應(yīng)該沒有沒用過tableView的吧,tableView里面會對dequeueReusableCellWithIdentifier申明的cell根據(jù)identifier進(jìn)行復(fù)用,而cell的復(fù)用相信會讓一些初學(xué)者有一些困擾,它是怎么實(shí)現(xiàn)復(fù)用的,為什么我這么寫,cell會變得好亂,完全不是我想要的。
而在平常的需求里面也會遇到一些需要橫向的可循環(huán)使用的視圖的需求
如下圖,

headTabbarWithViews.gif

如果每需要一個(gè)就重新創(chuàng)建一個(gè)view的話,這么多view會占用太多的內(nèi)存了,而且其實(shí)很多view,完全是占著茅坑不拉屎。所以,我們一般都會用復(fù)用其中的view,如果我們實(shí)現(xiàn)了這樣一個(gè)有復(fù)用視圖,對于以后多個(gè)imageViewtableView等就有一個(gè)比較好的處理方法了

以上就是我寫這個(gè)pageListView的原因, 1.增強(qiáng)對于復(fù)用的理解 2.便于平常項(xiàng)目里面對于一些可重復(fù)使用的view做一個(gè)簡單地集成封裝。

其實(shí)我們要實(shí)現(xiàn)的pageListView復(fù)用的原理和tableView對于cell的復(fù)用的原理基本一致,只是簡單了很多。因?yàn)槲覀兡壳翱紤]的都是一頁一頁的切換。所以不必考慮這個(gè)viewsize和滑動(dòng)完之后停留在兩個(gè)view中間的情況。

簡單說一下我們目前的思路,其實(shí)和tableViewCell復(fù)用的機(jī)制類似,創(chuàng)建兩個(gè)池子,一個(gè)放可視區(qū)域的views,另一個(gè)放可復(fù)用views。當(dāng)需要展示一個(gè)view,而復(fù)用池為空時(shí),就創(chuàng)建一個(gè)新的view,并將這個(gè)view放在可視views池,如果一個(gè)view已經(jīng)完全出了可視區(qū)域,就把它放入復(fù)用池,每次加載view的時(shí)候給view設(shè)置一下frame。
上面講了最基本的思路,下面讓我們來實(shí)現(xiàn)看看。

https://github.com/redihd/PageListView
這個(gè)是我實(shí)現(xiàn)一個(gè)可復(fù)用的pageListView的代碼,想看的可以拉下來看一下。
下面我會用我實(shí)現(xiàn)的代碼來做簡單的講解。

pageView.h

因?yàn)橐獙?shí)現(xiàn)的view很簡單,所以我們在.h文件中也沒有太多的屬性與方法,主要就是有個(gè)三個(gè)block來實(shí)現(xiàn)類似tableViewdatasourcedelegate。其中loadViewAtIndexBlock 需要兩個(gè)傳入?yún)?shù),會有一個(gè)返回的view,這個(gè)block實(shí)現(xiàn)了類似- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;這個(gè)方法。在接下來我們會細(xì)講這個(gè)block的功能。
再來看.m文件里面的屬性

pageview.m頭

我們將一些不需要對外暴露的都放在了.m中,其中兩個(gè)屬性visibleListViewsItems,dequeueViewPool是實(shí)現(xiàn)能夠復(fù)用viewpageView的關(guān)鍵。
visibleListViewsItems :這個(gè)可變字典用來存儲可視區(qū)域的視圖及其對應(yīng)的index。
dequeueViewPool:這個(gè)可變set用來存儲可復(fù)用的視圖。
.m文件中大多數(shù)方法都是設(shè)置frame,位移等,我們這里不談,主要介紹其中幾個(gè)關(guān)鍵方法

loadDequeueViewAndVisibleViewsIfNeeded.png

loadDequeueViewAndVisibleViewsIfNeeded該方法主要是在scrollview的contentOffset.x變化時(shí),計(jì)算應(yīng)該要在可視視圖字典中的視圖,把舊的可視視圖字典里面的視圖移動(dòng)到可重用視圖池,然后將要新的展示的視圖取出來,加入可視視圖字典。

loadViewAtIndex

loadViewAtIndex該方法主要是從我們datasourceblock獲取要展示的view,這個(gè)view默認(rèn)是從復(fù)用池即visibleListViewsItems任意取一個(gè)view來當(dāng)做我們將要展示的view,并將其與index加入visibleListViewsItems,如果block提供的view為空,再新建一個(gè)view。然后將原來在view要展示的位置的視圖(如果還有的話)移除,并加入visibleListViewsItems

基本思路就是這樣了

然后關(guān)于如何使用這個(gè)view

initPageView.png

totalPagesCountBlock 這個(gè)block設(shè)置有多少個(gè)view要展示
loadViewAtIndexBlock 這個(gè)block處理可重用的視圖
pageViewClickBlock 這個(gè)block處理點(diǎn)擊事件
個(gè)人比較喜歡用block,所以把delegate和datasource都用block來做了。

最后跑一下,可以看到,即使設(shè)置了60000個(gè),但是cpu和memory都還是很小。


run

最后,其實(shí)我們現(xiàn)在要實(shí)現(xiàn)這種視圖,用橫向的collectionView來做就好了。但是,寫一個(gè)這種對于個(gè)人理解一些東西的實(shí)現(xiàn)還是有幫助的。接下來可能會把這個(gè)寫的更詳細(xì),功能再多一些。
另外再就是自己用uiview實(shí)現(xiàn)一個(gè)缺一部分功能的scrollView。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,614評論 30 472
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,245評論 4 61
  • ①時(shí)間 你為旅行預(yù)備的時(shí)間是幾天?幾個(gè)月? 對于那些一言不合就任性長期旅行的土豪來說,時(shí)間就...
    熱鬧且孤獨(dú)閱讀 957評論 0 12
  • 我不喜歡習(xí)慣二字,但是更多的時(shí)候確是用習(xí)慣二字來隱飾無奈二字。 而我卻在不停的使用著習(xí)慣二字
    翦夢閱讀 307評論 15 18

友情鏈接更多精彩內(nèi)容