欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解iOS 滾動(dòng)視圖的復(fù)用問題解決方案

 更新時(shí)間:2016年12月28日 10:36:06   作者:code_xzh  
本篇文章主要介紹iOS 滾動(dòng)視圖的復(fù)用問題解決方案,具有一定的參考價(jià)值,有興趣的可以了解一下。

LazyScroll是什么

LazyScrollView 繼承自ScrollView,目標(biāo)是解決異構(gòu)(與TableView的同構(gòu)對(duì)比)滾動(dòng)視圖的復(fù)用回收問題。它可以支持跨View層的復(fù)用,用易用方式來生成一個(gè)高性能的滾動(dòng)視圖。

為什么要用LazyScrollView

我們?cè)谧鍪醉摰臅r(shí)候,往往展示的東西會(huì)很多,隨著View數(shù)量逐漸膨脹,沒有一套復(fù)用回收機(jī)制的ScrollView已經(jīng)影響到性能了,迫切需要處理對(duì)ScrollView中View的復(fù)用和回收。使用TableView只能用來解決同類Cell的展示,然而在實(shí)際的場(chǎng)景中在ScrollView里面,View的種類往往會(huì)比較多,所以使用TableView不適合我們的場(chǎng)景。
而UICollectionView本身的布局和復(fù)用回收機(jī)制不夠靈活,用起來也較為繁瑣。所以誕生了LazyScrollView去解決這個(gè)問題。這也是天貓iOS客戶端的首頁落地方案。

LazyScroll使用

LazyScrollView的使用和TableView很像,不過多了一個(gè)需要實(shí)現(xiàn)的方法:返回對(duì)應(yīng)index的View 相對(duì)LazyScrollView的絕對(duì)坐標(biāo)。

實(shí)現(xiàn)LazyScrollViewDatasource

類似TableView的用法,我們需要使用方實(shí)現(xiàn)LazyScrollViewDatasource的Delegate。

@protocol TMMuiLazyScrollViewDataSource <NSObject>
@required
//ScrollView展示item個(gè)數(shù)
- (NSUInteger)numberOfItemInScrollView:(TMMuiLazyScrollView *)scrollView;
//要求根據(jù)index直接返回RectModel
- (TMMuiRectModel *)scrollView:(TMMuiLazyScrollView *)scrollView rectModelAtIndex:(NSUInteger)index;
//返回下標(biāo)所對(duì)應(yīng)的view
- (UIView *)scrollView:(TMMuiLazyScrollView *)scrollView itemByMuiID:(NSString *)muiID;

LazyScrollView的核心是在初始狀態(tài)就得知所有View應(yīng)該顯示的位置。第一個(gè)方法很簡(jiǎn)單,獲取LazyScrollView中item的個(gè)數(shù)。第二個(gè)方法需要按照Index返回TMMuiRectModel ,它會(huì)攜帶對(duì)應(yīng)index的View 相對(duì)LazyScrollView的絕對(duì)坐標(biāo)。

這里出現(xiàn)了一個(gè)TMMuiRectModel ,這是個(gè)什么東西呢?我們看一下代碼:

@interface TMMuiRectModel:NSObject
//轉(zhuǎn)換后的絕對(duì)值rect
@property (nonatomic,assign) CGRect absRect;
//業(yè)務(wù)下標(biāo)
@property (nonatomic,copy) NSString *muiID;

這里有兩個(gè)屬性,absRect是LazyScroll中的View相對(duì)LazyScrollView的絕對(duì)坐標(biāo),muiID是這個(gè)View在LazyScrollView中唯一的標(biāo)識(shí)符,可賦值也可不賦值。

第三個(gè)方法,返回View。

@interface UIView(TMMui)

//索引過的標(biāo)識(shí),在LazyScrollView范圍內(nèi)唯一
@property (nonatomic, copy) NSString *muiID;
//重用的ID
@property (nonatomic, copy) NSString *reuseIdentifier;

首先,我們?cè)赨IView之外加了一個(gè)Category,這個(gè)category可以讓View攜帶muiID和reuseIdentifier,對(duì)于返回的View來說,只需要在乎對(duì)View的reuseIdentifier賦值,muiID的賦值會(huì)在lazyScrollView中處理掉。reuseIdentifier相同的View會(huì)被復(fù)用,如果這個(gè)View的reuseIdentifier是nil或者空字符串,則不會(huì)被復(fù)用。

LazyScrollView內(nèi)部原理分析

首先來看一個(gè)簡(jiǎn)單的案例:

根據(jù)DataSource獲取所有的TMMuiRectModel

根據(jù)DataSource的Delegate,拿到所有的View應(yīng)該被顯示的位置。這一步,核心是拿到的位置是確定的。根據(jù)Demo,我們觀察從 0/1 - 2/3 之間這些View,這個(gè)時(shí)候LazyScrollView拿到的Rect如下:

Index 標(biāo)號(hào)(MUIID) Rect
0 0/0 origin = (x = 25, y = 15), size = (width = 156, height = 150
1 0/1 origin = (x = 194, y = 15), size = (width = 156, height = 150)
2 0/2 origin = (x = 25, y = 180), size = (width = 156, height = 150)
3 0/3 origin = (x = 194, y = 180), size = (width = 156, height = 150
4 1/0 origin = (x = 5, y = 360), size = (width = 177.5, height = 150)
5 1/1 origin = (x = 192.5, y = 426), size = (width = 84, height = 84)
6 1/2 origin = (x = 192.5, y = 360), size = (width = 177.5, height = 56)
7 1/3 origin = (x = 286.5, y = 426), size = (width = 83.5, height = 84)
8 2/0 origin = (x = 25, y = 530), size = (width = 325, height = 150)
9 2/1 origin = (x = 25, y = 695), size = (width = 325, height = 150)
10 2/2 origin = (x = 25, y = 860), size = (width = 325, height = 150)

排序

拿到了這些位置之后,接下來做的事情就是排序。排序生成的索引會(huì)有兩個(gè):根據(jù)頂邊(y)升序排序的索引和根據(jù)底邊(y+height)降序排序的索引。

根據(jù)頂邊(y)升序排序的索引

Index 標(biāo)號(hào)(MUIID) Rect
0 0/0 origin = (x = 25, y = 15), size = (width = 156, height = 150
1 0/1 origin = (x = 194, y = 15), size = (width = 156, height = 150)
2 0/2 origin = (x = 25, y = 180), size = (width = 156, height = 150)
3 0/3 origin = (x = 194, y = 180), size = (width = 156, height = 150
4 1/0 origin = (x = 5, y = 360), size = (width = 177.5, height = 150)
5 1/1 origin = (x = 192.5, y = 360), size = (width = 177.5, height = 56)
6 1/2 origin = (x = 192.5, y = 360), size = (width = 177.5, height = 56)
7 1/3 origin = (x = 286.5, y = 426), size = (width = 83.5, height = 84)
8 2/0 origin = (x = 25, y = 530), size = (width = 325, height = 150)
9 2/1 origin = (x = 25, y = 695), size = (width = 325, height = 150)
10 2/2 origin = (x = 25, y = 860), size = (width = 325, height = 150)

根據(jù)底邊(y+height)降序排序的索引

Index 標(biāo)號(hào)(MUIID) Rect
0 2/2 origin = (x = 25, y = 860), size = (width = 325, height = 150)
1 2/1 origin = (x = 25, y = 695), size = (width = 325, height = 150)
2 2/0 origin = (x = 25, y = 530), size = (width = 325, height = 150)
3 1/0 origin = (x = 5, y = 360), size = (width = 177.5, height = 150)
4 1/2 origin = (x = 192.5, y = 360), size = (width = 177.5, height = 56)
5 1/3 origin = (x = 286.5, y = 426), size = (width = 83.5, height = 84)
6 1/1 origin = (x = 192.5, y = 426), size = (width = 84, height = 84)
7 0/2 origin = (x = 25, y = 180), size = (width = 156, height = 150)
8 0/3 origin = (x = 194, y = 180), size = (width = 156, height = 150
9 0/0 origin = (x = 25, y = 15), size = (width = 156, height = 150
10 0/1 origin = (x = 194, y = 15), size = (width = 156, height = 150)

查找

前兩步是在執(zhí)行完reload,在視圖還沒有生成的時(shí)候就開始做了,而接下來的步驟在要生成視圖(初始化或滾動(dòng)的時(shí)候)才會(huì)去做。

我們?cè)O(shè)定了Buffer為上下各20,滾動(dòng)超過20個(gè)像素后才會(huì)指定查找視圖并顯示的動(dòng)作。舉個(gè)例子,如下圖,紅圈是應(yīng)該顯示的區(qū)域。

如上圖所示,現(xiàn)在已知的是紅圈頂邊y是242,底邊y是949,加上緩沖區(qū)Buffer,應(yīng)該是找222 - 969 之間的View。我們要做的是,找到底邊y小于969的Model和頂邊y大于222的Model,取交集,就是我們要顯示的View。

采用的方法為二分查找,在根據(jù)頂邊升序排序的索引中找949,找到的index為0(MUIID為2/2),我們使用一個(gè)Set,把根據(jù)頂邊排序中index >= 0 的元素先放在這里。獲取的Set中包含的muiID為 0/0,0/1,0/2,0/3,1/0,1/1,1/2,1/3,2/0,2/1,2/2。

根據(jù)底邊排序的索引中找222,找到的index為2,我們把index >= 2的元素放在另一個(gè)Set,獲取的Set中包含的muiID為0/2,0/3,1/0,1/1,1/2,1/3,2/0,2/1,2/2

兩個(gè)Set取交集,得到的就是我們的ResultSet,這里面都是我們要顯示View的Model,它們的muiID是0/2,0/3,1/0,1/1,1/2,1/3,2/0,2/1,2/2。

回收、復(fù)用、生成

我們知道了應(yīng)該顯示哪些View,但是我們之后做的第一步是把不需要顯示的View加入到復(fù)用池中。LazyScroll可以取到當(dāng)前顯示了的View,拿當(dāng)前顯示的View的muiID和將要顯示view的Model的muiID做對(duì)比,可以知道當(dāng)前顯示的View哪些應(yīng)該被回收。

LazyScrollView中有一個(gè)Dictionary,key是reuseIdentifier,Value是對(duì)應(yīng)reuseIdentifier被回收的View,當(dāng)LazyScrollView得知這個(gè)View不該再出現(xiàn)了,會(huì)把View放在這里,并且把這個(gè)View hidden掉。

然后,用LazyScrollView會(huì)去調(diào)用datasource。

- (UIView *)scrollView:(TMMuiLazyScrollView *)scrollView itemByMuiID:(NSString *)muiID;

復(fù)用還是不復(fù)用,是由datasource決定的。如果要復(fù)用,需要datasource方法內(nèi)調(diào)用,即:

- (UIView *)dequeueReusableItemWithIdentifier:(NSString *)identifier

獲取復(fù)用的View,這個(gè)方法取出來的View就是在上一段所說的Dictionary中拿的。
最后我們看一下LazyScrollView的使用流程:找到所有View將要顯示的位置 – 排序 – 查找應(yīng)該顯示的View – 回收 – 創(chuàng)建/復(fù)用。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • iOS?Swift?Lazy?var?View失效問題解決

    iOS?Swift?Lazy?var?View失效問題解決

    這篇文章主要為大家介紹了iOS?Swift?Lazy?var?View失效問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • iOS仿網(wǎng)易簡(jiǎn)單頭部滾動(dòng)效果

    iOS仿網(wǎng)易簡(jiǎn)單頭部滾動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了iOS仿網(wǎng)易簡(jiǎn)單頭部滾動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • 使用objc runtime實(shí)現(xiàn)iOS閉環(huán)的懶加載功能

    使用objc runtime實(shí)現(xiàn)iOS閉環(huán)的懶加載功能

    利用objc runtime的動(dòng)態(tài)性實(shí)現(xiàn)懶加載可以實(shí)現(xiàn)即可增加又可刪除功能,也可以避免污染類型。這篇文章主要介紹了使用objc runtime實(shí)現(xiàn)iOS閉環(huán)的懶加載功能,需要的朋友可以參考下
    2019-06-06
  • IOS中UITableView滾動(dòng)到指定位置

    IOS中UITableView滾動(dòng)到指定位置

    這篇文章主要介紹了IOS中UITableView滾動(dòng)到指定位置的實(shí)現(xiàn)方法,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • iOS實(shí)現(xiàn)相冊(cè)多選圖片上傳功能

    iOS實(shí)現(xiàn)相冊(cè)多選圖片上傳功能

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)相冊(cè)多選圖片上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • iOS Crash文件分析方法匯總

    iOS Crash文件分析方法匯總

    今天跟大家一起聊聊iOSCrash文件的幾種分析方法,都是平時(shí)比較常用的,有需要的小伙伴可以參考下
    2017-11-11
  • IOS 仿支付寶支付屏幕亮度變化機(jī)制

    IOS 仿支付寶支付屏幕亮度變化機(jī)制

    這篇文章主要介紹了IOS 仿支付寶支付屏幕亮度變化機(jī)制的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • ios開發(fā)UITableViewCell圖片加載優(yōu)化詳解

    ios開發(fā)UITableViewCell圖片加載優(yōu)化詳解

    這篇文章主要為大家介紹了ios開發(fā)UITableViewCell圖片加載優(yōu)化的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • iOS Swift控制器轉(zhuǎn)場(chǎng)動(dòng)畫示例代碼

    iOS Swift控制器轉(zhuǎn)場(chǎng)動(dòng)畫示例代碼

    這篇文章主要給大家介紹了關(guān)于iOS Swift控制器轉(zhuǎn)場(chǎng)動(dòng)畫的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • iOS視頻錄制(或選擇)壓縮及上傳功能(整理)

    iOS視頻錄制(或選擇)壓縮及上傳功能(整理)

    最新做的一個(gè)功能涉及到了視頻的錄制、壓縮及上傳功能,經(jīng)過大神的一番教導(dǎo),終于倒騰清楚了,今天小編把問題經(jīng)過記錄一下分享到腳本之家平臺(tái),供大家參考
    2017-03-03

最新評(píng)論