最近在做项目,也遇到了各种奇奇怪怪的需求,有个需求一开始看起来有点难搞,但是在大神的指导下,既然做不到那种气泡,那我们就用魔术般切换Cell不就好了么,我用的是纯Autolayout,直观暴力,用习惯了真的强,把效果贴出来还蛮不错的,花了一小时写出了Demo给大家分享下。
Demo效果
1.首先我用的tableView实现的
2.我用了两套cell切换 第二套cell内嵌了collectionView
3.最关键的是由于用的tableView实现,点击每个image的时候回调进行了一些逻辑处理
4.高度计算和模型解析用了FDTemplateLayout和MJExtension 想用的请进传送!!
第一步
上面也提到了我用了两套cell,而且我用的也不是代码布局UI,那么直接点,贴几个图
你们自行感受下
普通状态下
下拉状态下
熟练用IB的应该很容易能看明白,三个ImageView三等分屏幕,高度是宽度的0.8倍,
这里的collectionView高度固定给的200,内容小于200缩短,大于200滚动
无需繁琐的代码,这布局几分钟就写完了,啦啦啦啦
第二步
还是贴一段解析本地数据的用法,我用的MJExtension,好用啊,也是非常迅速
快到不能呼吸,貌似我另一篇文章也有介绍,这里不多说了
- (void)requestCategoryInfo:(requestHelperBlock)block
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"Category" ofType:@"json"];
NSString *categoryStr = [NSString stringWithContentsOfFile:path usedEncoding:nil error:nil];
NSArray *categoryArr = [categoryStr mj_JSONObject];
// 直接给数组里面的字典进行模型赋值
[CategoryInfomation mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{@"categoryID":@"id",
@"categoryPic":@"pic",
@"categoryName":@"group",
@"secondClassificationLists":@"list"
};
}];
[CategoryInfomation mj_setupObjectClassInArray:^NSDictionary *{
return @{@"secondClassificationLists":@"SecondCategoryInfomation"};
}];
// 子模型
[SecondCategoryInfomation mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{@"secondCategoryID":@"id",
@"secondCategoryName":@"name"
};
}];
// 通过数组加载数组模型,这里的类TWTBuyerMarket就是模型数组里面的小集合
NSMutableArray *dataLists = [CategoryInfomation mj_objectArrayWithKeyValuesArray:categoryArr];
// 把对应的每个分组的一级分组加入到二级分组里面去
for (CategoryInfomation *category in dataLists)
{
NSMutableArray *secondLists = category.secondClassificationLists;
SecondCategoryInfomation *secondNewModel = [[SecondCategoryInfomation alloc] init];
secondNewModel.secondCategoryID = category.categoryID;
secondNewModel.secondCategoryName = category.categoryName;
[secondLists insertObject:secondNewModel atIndex:0];
}
if (block)
{
block(dataLists,nil);
}
}
tableView的布局就不介绍了,高度计算简单提下
// 给CollectionView加载对应的数据 selectedIndex传的是具体的 0 1 2哪一个被点击了 同时拿出collectionView的高度
NSInteger idx = indexpath.row * 3 + selectedIndex;
CategoryInfomation *category = self.categoryLists[idx];
cell.secondClassificationLists = category.secondClassificationLists;
cell.collectionView.width = SCREEN_WIDTH;
[cell.collectionView reloadData];
cell.selectedHeightConstraint.constant = cell.collectionView.collectionViewLayout.collectionViewContentSize.height > 200 ? 200 : cell.collectionView.collectionViewLayout.collectionViewContentSize.height;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
CGFloat singleWidth = (SCREEN_WIDTH - 6) / 3;
__weak typeof(self)weakSelf = self;
// 能被整除,那么肯定都展示三个
if (self.canDivisible)
{
CategoryInfomation *category = self.categoryLists[indexPath.row * 3 + 0];
CategoryInfomation *category1 = self.categoryLists[indexPath.row * 3 + 1];
CategoryInfomation *category2 = self.categoryLists[indexPath.row * 3 + 2];
// 三个钟有一个是需要打开的,那么就加载选择状态下的cell
if (category.needShowSecondClassification || category1.needShowSecondClassification || category2.needShowSecondClassification)
{
NSInteger selectedIndex;
if (category.needShowSecondClassification)
{
selectedIndex = 0;
}
else if (category1.needShowSecondClassification)
{
selectedIndex = 1;
}
else
{
selectedIndex = 2;
}
return [tableView fd_heightForCellWithIdentifier:selectedIdentify cacheByIndexPath:indexPath configuration:^(CategoryNormalTableViewCell *cell)
{
[weakSelf configSelectedCell:cell indexpath:indexPath selectedIndex:selectedIndex];
}];
}
else
{
return 0.8 * singleWidth + 3;
}
}
return 0;
}
点击事件切换cell,实现Demo的效果,直接看代码来的实在
#pragma mark - 点击图片的代理回调
- (void)clickImageViewCallBack:(CategoryNormalTableViewCell *)cell imageIndex:(NSInteger)idx
{
// 获取到那个Indexpath
NSIndexPath *indexpath = [self.tableView indexPathForCell:cell];
// 获取到数组里面的第几个
NSInteger index = indexpath.row * 3 + idx;
// 获取对象
CategoryInfomation *category = self.categoryLists[index];
// 修改字段
// 点击同一个
if (self.tempCategoryInfomation == category)
{
category.needShowSecondClassification = !category.needShowSecondClassification;
}
else
{
category.needShowSecondClassification = YES;
}
// 点击的每一次事件,都要让上一次存储的对象的需要展开变为NO
if (self.tempCategoryInfomation)
{
// 如果是同一行的情况下
if (indexpath.row == self.tempIndexpath.row)
{
// 如果是同一个产品
if (self.tempCategoryInfomation == category)
{
}
else // 不同一个产品
{
self.tempCategoryInfomation.needShowSecondClassification = NO;
}
[self.tableView reloadRowsAtIndexPaths:@[indexpath] withRowAnimation:UITableViewRowAnimationAutomatic];
self.tempIndexpath = indexpath;
self.tempCategoryInfomation = category;
return;
}
else // 不是同一行的时候
{
self.tempCategoryInfomation.needShowSecondClassification = NO;
[self.tableView reloadRowsAtIndexPaths:@[self.tempIndexpath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
[self.tableView reloadRowsAtIndexPaths:@[indexpath] withRowAnimation:UITableViewRowAnimationAutomatic];
// 往上滚动,以免点击后面几行遮住二级分类
[self.tableView scrollToRowAtIndexPath:indexpath atScrollPosition:UITableViewScrollPositionTop animated:YES];
// 记得把本地点击的信息存储下来
self.tempIndexpath = indexpath;
self.tempCategoryInfomation = category;
}
小白写的Demo,大神有什么意见请指教,其实也只是提供一个思路,有的朋友肯定认
为用collectionView写好一点,如果有想法的朋友可以自己试试,反正用不了几分钟,
蛮快的,记得分享哦
本地Demo地址:点击打开链接
噢。。。。。。NO,我把神器Reveal给pod进去了,怪不得工程那么大,10M啊,各位
如果有朋友用了Reveal,可以直接打开看看结构哦,已经给您加载好了,这个东西非常强,还能看淘宝和京东等所有App的结构,太强了
点击打开链接