最近看了看YY微博的實現(xiàn)渗勘,用小本子記了記筆記。
先上一個簡略的流程圖:
-
首先后臺線程異步的去請求數(shù)據(jù)(從JSON文件取)张惹,初始化WBStatusLayout類來接受數(shù)據(jù),然后根據(jù)數(shù)據(jù)計算好業(yè)務(wù)所需要的布局信息(這個類就是核心類)岭洲,這個工作結(jié)束后回到主線程刷新UITableView宛逗。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i = 0; i <= 7; i++) {
NSData *data = [NSData dataNamed:[NSString stringWithFormat:@"weibo_%d.json",i]];
WBTimelineItem *item = [WBTimelineItem modelWithJSON:data];
for (WBStatus *status in item.statuses) {
WBStatusLayout *layout = [[WBStatusLayout alloc] initWithStatus:status style:WBLayoutStyleTimeline];
[_layouts addObject:layout];
}
}// 復(fù)制一下,讓列表長一些盾剩,不至于滑兩下就到底了 [_layouts addObjectsFromArray:_layouts]; dispatch_async(dispatch_get_main_queue(), ^{ self.title = [NSString stringWithFormat:@"Weibo (loaded:%d)", (int)_layouts.count]; [indicator removeFromSuperview]; self.navigationController.view.userInteractionEnabled = YES; [_tableView reloadData]; });
});
下面這個方法就是WBStatusLayout類根據(jù)存儲圖片數(shù)據(jù)的個數(shù)來布局“9宮格圖片雷激。WBStatusLayout會計算出每個 cell的高度和相關(guān)布局信息緩存下來。這樣再次滑動UITableView直接從緩存里面提取就好了彪腔,并不會再次計算侥锦。
- (void)_layoutPicsWithStatus:(WBStatus *)status isRetweet:(BOOL)isRetweet {
if (isRetweet) {
_retweetPicSize = CGSizeZero;
_retweetPicHeight = 0;
} else {
_picSize = CGSizeZero;
_picHeight = 0;
}
if (status.pics.count == 0) return;
CGSize picSize = CGSizeZero;
CGFloat picHeight = 0;
CGFloat len1_3 = (kWBCellContentWidth + kWBCellPaddingPic) / 3 - kWBCellPaddingPic;
len1_3 = CGFloatPixelRound(len1_3);
switch (status.pics.count) {
case 1: {
WBPicture *pic = _status.pics.firstObject;
WBPictureMetadata *bmiddle = pic.bmiddle;
if (pic.keepSize || bmiddle.width < 1 || bmiddle.height < 1) {
CGFloat maxLen = kWBCellContentWidth / 2.0;
maxLen = CGFloatPixelRound(maxLen);
picSize = CGSizeMake(maxLen, maxLen);
picHeight = maxLen;
} else {
CGFloat maxLen = len1_3 * 2 + kWBCellPaddingPic;
if (bmiddle.width < bmiddle.height) {
picSize.width = (float)bmiddle.width / (float)bmiddle.height * maxLen;
picSize.height = maxLen;
} else {
picSize.width = maxLen;
picSize.height = (float)bmiddle.height / (float)bmiddle.width * maxLen;
}
picSize = CGSizePixelRound(picSize);
picHeight = picSize.height;
}
} break;
case 2: case 3: {
picSize = CGSizeMake(len1_3, len1_3);
picHeight = len1_3;
} break;
case 4: case 5: case 6: {
picSize = CGSizeMake(len1_3, len1_3);
picHeight = len1_3 * 2 + kWBCellPaddingPic;
} break;
default: { // 7, 8, 9
picSize = CGSizeMake(len1_3, len1_3);
picHeight = len1_3 * 3 + kWBCellPaddingPic * 2;
} break;
}
if (isRetweet) {
_retweetPicSize = picSize;
_retweetPicHeight = picHeight;
} else {
_picSize = picSize;
_picHeight = picHeight;
}
}
- 通過下面協(xié)議方法去給Cell相關(guān)信息。非常簡潔德挣。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellID = @"cell";
WBStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if (!cell) {
cell = [[WBStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
cell.delegate = self;
}
[cell setLayout:_layouts[indexPath.row]];
return cell;
}
YY的代碼真心寫的非常的漂亮恭垦。特別是把Cell所有的事件通過WBStatusCellDelegate代理進行統(tǒng)一的管理,提高了代碼的可讀性格嗅。
/// 點擊了 Cell
- (void)cellDidClick:(WBStatusCell *)cell;
/// 點擊了 Card
- (void)cellDidClickCard:(WBStatusCell *)cell;
/// 點擊了轉(zhuǎn)發(fā)內(nèi)容
- (void)cellDidClickRetweet:(WBStatusCell *)cell;
/// 點擊了Cell菜單
- (void)cellDidClickMenu:(WBStatusCell *)cell;
/// 點擊了關(guān)注
- (void)cellDidClickFollow:(WBStatusCell *)cell;
/// 點擊了轉(zhuǎn)發(fā)
- (void)cellDidClickRepost:(WBStatusCell *)cell;
/// 點擊了下方 Tag
- (void)cellDidClickTag:(WBStatusCell *)cell;
/// 點擊了評論
- (void)cellDidClickComment:(WBStatusCell *)cell;
/// 點擊了贊
- (void)cellDidClickLike:(WBStatusCell *)cell;
/// 點擊了用戶
- (void)cell:(WBStatusCell *)cell didClickUser:(WBUser *)user;
/// 點擊了圖片
- (void)cell:(WBStatusCell *)cell didClickImageAtIndex:(NSUInteger)index;
/// 點擊了 Label 的鏈接
- (void)cell:(WBStatusCell *)cell didClickInLabel:(YYLabel *)label textRange:(NSRange)textRange;
在這里我只是簡略的去做了一個梳理番挺。如果您有興趣可以去github上下載下來讀讀源碼。
YYkit github : https://github.com/ibireme/YYKit