LazyScrollView是阿里iOS端,针对ScrollView做的一个解决异构(与TableView的同构对比)滚动视图的复用回收问题的解决方案。
LazyScrollView文档
苹果核 - iOS 高性能异构滚动视图构建方案 —— LazyScrollView
使用场景
一般的如果是同一类型的cell,或者cell类型不是特别多的话TableView实现起来还是比较方便。
LazyScrollView是为了解决view种类特别多,使用TableView定制cell麻烦的问题。
这个开源库比较早了,我看最后更新是在两年前,使用LazyScrollView还是使用tableView需要根据具体的业务来定。
Demo
集成
pod ‘LazyScroll’
如果报缺少framework的库的话,将Podfile里面的 use_frameworks!
行注释掉,添加上 use_modular_headers!
使用静态库好了。因为我的确是遇到这个问题,所以这里赘述一下。
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'Test-1' do
# Comment the next line if you don't want to use dynamic frameworks
# use_frameworks!
use_modular_headers!
# Pods for Test-1
pod 'LazyScroll'
end
Demo
开元库里面的Demo演示简单明了,很容易读,自己写了一个与Demo中思想有点不同的是,我创建旅了一个类ScrollViewItemModel,这个类作为数据源模型。
- ScrollViewItemModel
ScrollViewItemModel.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "TMLazyItemModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface ScrollViewItemModel : NSObject
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithTMLazyItem:(TMLazyItemModel *)item;
// TMLazyItemModel
@property (nonatomic, strong, readonly) TMLazyItemModel *item;
// 内容
@property (nonatomic, copy) NSString *text;
// 背景颜色
@property (nonatomic, strong) UIColor *backgroundColor;
@end
NS_ASSUME_NONNULL_END
ScrollViewItemModel.m
#import "ScrollViewItemModel.h"
@interface ScrollViewItemModel ()
@property (nonatomic, strong, readwrite) TMLazyItemModel *item;
@end
@implementation ScrollViewItemModel
- (instancetype)initWithTMLazyItem:(TMLazyItemModel *)item {
if (self = [super init]) {
self.item = item;
}
return self;
}
@end
- ViewController
ViewController.m
#import "ViewController.h"
#import "LazyScroll.h"
#import "ScrollViewItemModel.h"
@interface ViewController ()<TMLazyScrollViewDataSource>
@property (nonatomic, strong) TMLazyScrollView *scrollView;
@property (nonatomic, strong) NSMutableArray <ScrollViewItemModel *> *dataSource;
@end
@implementation ViewController
- (TMLazyScrollView *)scrollView {
if (!_scrollView) {
_scrollView = [[TMLazyScrollView alloc] initWithFrame:self.view.bounds];
_scrollView.autoAddSubview = YES;
_scrollView.dataSource = self;
}
return _scrollView;;
}
- (NSMutableArray<ScrollViewItemModel *> *)dataSource {
if (!_dataSource) {
_dataSource = [[NSMutableArray alloc] init];
}
return _dataSource;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initViews];
[self initData];
}
- (void)initViews {
[self.view insertSubview:self.scrollView atIndex:0];
}
- (void)initData {
CGFloat maxY = 0;
CGFloat currentY = 20;
CGFloat viewWidth = CGRectGetWidth(self.view.bounds);
for (int i = 0; i < 15; i++)
{
TMLazyItemModel *item = [[TMLazyItemModel alloc] init];
item.absRect = CGRectMake(10 + (i % 2) * ((viewWidth - 20 + 3) / 2), i / 2 * 80 + currentY, (viewWidth - 20 - 3) / 2, 80 - 3);
ScrollViewItemModel *model = [[ScrollViewItemModel alloc] initWithTMLazyItem:item];
model.text = [NSString stringWithFormat:@"%d",i];
model.backgroundColor = [ViewController randomColor];
[self.dataSource addObject:model];
if (CGRectGetMaxY(item.absRect) > maxY) {
maxY = CGRectGetMaxY(item.absRect);
}
}
currentY = maxY + 10;
for (int i = 0; i < 15; i++)
{
TMLazyItemModel *item = [[TMLazyItemModel alloc] init];
item.absRect = CGRectMake(10, i * 80 + currentY, viewWidth - 20, 80 - 3);
ScrollViewItemModel *model = [[ScrollViewItemModel alloc] initWithTMLazyItem:item];
model.text = [NSString stringWithFormat:@"%d",i+15];
model.backgroundColor = [ViewController randomColor];
[self.dataSource addObject:model];
if (CGRectGetMaxY(item.absRect) > maxY) {
maxY = CGRectGetMaxY(item.absRect);
}
}
currentY = maxY + 10;
for (int i = 0; i < 15; i++)
{
TMLazyItemModel *item = [[TMLazyItemModel alloc] init];
item.absRect = CGRectMake((i % 2) * (viewWidth - 20 + 3) / 2 + 10, i / 2 * 80 + currentY, (viewWidth - 20 - 3) / 2, 80 - 3);
ScrollViewItemModel *model = [[ScrollViewItemModel alloc] initWithTMLazyItem:item];
model.text = [NSString stringWithFormat:@"%d",i+30];
model.backgroundColor = [ViewController randomColor];
[self.dataSource addObject:model];
if (CGRectGetMaxY(item.absRect) > maxY) {
maxY = CGRectGetMaxY(item.absRect);
}
}
self.scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.view.bounds), maxY+10);
[self.scrollView reloadData];
}
#pragma mark - TMLazyScrollViewDataSource
- (NSUInteger)numberOfItemsInScrollView:(nonnull TMLazyScrollView *)scrollView {
return self.dataSource.count;
}
- (nonnull TMLazyItemModel *)scrollView:(nonnull TMLazyScrollView *)scrollView
itemModelAtIndex:(NSUInteger)index {
return self.dataSource[index].item;
}
- (nonnull UIView *)scrollView:(nonnull TMLazyScrollView *)scrollView
itemByMuiID:(nonnull NSString *)muiID
{
static NSString *reusableIdentifier = @"ViewController_TMLazyScrollView";
UILabel *label = (UILabel *)[scrollView dequeueReusableItemWithIdentifier:reusableIdentifier];
if (label == nil) {
label = [[UILabel alloc] init];
label.textAlignment = NSTextAlignmentCenter;
label.numberOfLines = 0;
label.reuseIdentifier = reusableIdentifier;
NSLog(@"创建了新的label");
}
//读view对应的index
NSInteger index = [muiID integerValue];
//从数据源中取出对应的数据模型
ScrollViewItemModel *model = self.dataSource[index];
//给view赋值等其他操作在这里处理
label.text = model.text;
label.backgroundColor = model.backgroundColor;
//这里一定要注意设置view的frame
label.frame = model.item.absRect;
return label;
}
#pragma mark Private
+ (UIColor *)randomColor {
CGFloat hue = (arc4random() %256/256.0);
CGFloat saturation = (arc4random() %128/256.0) +0.5;
CGFloat brightness = (arc4random() %128/256.0) +0.5;
return [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1.0];
}
@end
整体上和阿里提供的Demo差不多,使用方法什么的人家的文档里面说的非常清楚,唯一一点不同是我将ScrollViewItemModel作为一个纯粹的数据模型,它里面包含有我们view上所需要的任何数据,包括TMLazyItemModel的实例,这样一是做一个简单的功能扩展,二是也不用每次刷新都去创建TMLazyItemModel的实例。
上面这些只是简单的会用,读源码的话会使我们学习更多。