LazyScrollView 終於被開源了,一些東西可以被拿出來繼續說一下。
Github 鏈接 : https://github.com/alibaba/LazyScrollView
如果是第一次接觸LazyScrollView,建議先看一下之前的文章,了解一下具體原理http://pingguohe.net/2016/01/31/lazyscroll.html
Demo請直接Clone Github工程,在master分支,打開LazyScrollViewDemo文件夾下的工程
具體用法都在ViewController這個類內。
創建視圖
TMMuiLazyScrollView *scrollview = [[TMMuiLazyScrollView alloc]init]; scrollview.frame = self.view.bounds; scrollview.dataSource = self; [self.view addSubview:scrollview];
和正常的ScrollView一樣init即可,只需要注意一點的是,需要有一個實現TMMuiLazyScrollViewDataSource的類,賦給LazyScrollView的dataSource
實現 TMMuiLazyScrollViewDataSource
返回View個數
- (NSUInteger)numberOfItemInScrollView:(TMMuiLazyScrollView *)scrollView
這裡需要返回view的個數,決定返回多少個rectModel
返回RectModel
- (TMMuiRectModel *)scrollView:(TMMuiLazyScrollView *)scrollView rectModelAtIndex:(NSUInteger)index
根據index返回TMMuiRectModel
TMMuiRectModel有兩個屬性,一個是muiID,它是View的唯一標識符, 另一個是absoluteRect,是對應的View在LazyScrollView內的絕對坐標
按需返回視圖
- (UIView *)scrollView:(TMMuiLazyScrollView *)scrollView itemByMuiID:(NSString *)muiID
這個方法在需要生成即將進入屏幕的視圖的時候,會被LazyScrollView按需調用 muiID就是rectModel的muiID,可以根據muiID生成相關的View
這裡一般會先去找復用的視圖,沒有再做生成
Demo中這個方法內部的寫法是:
LazyScrollViewCustomView *label = (LazyScrollViewCustomView *)[scrollView dequeueReusableItemWithIdentifier:@"testView"]; NSInteger index = [muiID integerValue]; if (!label) { label = [[LazyScrollViewCustomView alloc]initWithFrame:[(NSValue *)[rectArray objectAtIndex:index]CGRectValue]]; label.textAlignment = NSTextAlignmentCenter; label.reuseIdentifier = @"testView"; } label.frame = [(NSValue *)[rectArray objectAtIndex:index]CGRectValue]; label.text = [NSString stringWithFormat:@"%lu",(unsigned long)index];
流程是:先取一下復用池中可復用的View,有的話,賦給對應的frame,沒有的話,生成一個,並給予一個復用標記。
在 LazyScrollView 中聲明的一個對UIView 的 category 中包含了 reuseIdentifier,可以給任意的View綁定這個屬性。如果沒有賦值reuseIdentifier或者給一個nil/空字符串,會認為這個組件不復用。
刷新視圖
設置一下contentSize , 並且Reload一下即可。
scrollview.contentSize = CGSizeMake(CGRectGetWidth(self.view.bounds), 1230); [scrollview reloadData];
視圖生命周期
Demo中的LazyScrollViewCustomView實現了TMMuiLazyScrollViewCellProtocol的三個方法,可以在組件的生命周期的時候執行相關代碼
- (void)mui_prepareForReuse
在即將被復用時調用,通常用於清空View內展示的數據。類似與UITableViewCell 的 prepareForReuse
- (void)mui_didEnterWithTimes:(NSUInteger)times
進入屏幕LazyScroll可視范圍內時執行,times是進入可視范圍的次數,從0開始。重置times可以調用LazyScrollView的resetViewEnterTimes重置times
- (void)mui_afterGetView
LazyScroll獲取到View後執行。也就是執行完- (UIView *)scrollView:(TMMuiLazyScrollView *)scrollView itemByMuiID:(NSString *)muiID方法獲取到視圖之後。
和didEnterWithTimes的區別是,因為LazyScrollView有一個RenderBuffer的概念,實際渲染的視圖比可視范圍上下各增加了20個像素,使得展示更加流暢。afterGetView會執行的更早。
後續
LazyScrollView 屬於相對底層的視圖層,在復用上提供的比較高的靈活度。一些更高程度的封裝,比如類似UICollection的Layout,對復用更簡易的管理,對組件的解析、賦值等管理,我們都放在了Tangram裡面,關於Tangram 可見 http://pingguohe.net/2016/12/20/Tangram-design-and-practice.html
Tangram的開源計劃也在進行之中,敬請期待。