UICollectionView二级树展开

公司项目是社区类的,上周就下载了些社区类APP看了下,发现小区无忧首页的顶部蛮好玩,就试着做了一下,现在先把UICollectionView的二级树展开功能分享一下 .

1.效果图

2.创建子CollectionView

//
//  DeatilView.h
//  Spread
//
//  Created by City--Online on 15/10/30.
//  Copyright  2015年 City--Online. All rights reserved.
//

#import <UIKit/UIKit.h>

typedef void(^DetailIndexPathBlock) (NSIndexPath *indexPath);

@interface DetailView : UIView

@property (nonatomic,copy) DetailIndexPathBlock detailIndexPathBlock;

- (instancetype)initWithFrame:(CGRect)frame withTitleArray:(NSArray *)titleArray;

@end

//
//  DeatilView.m
//  Spread
//
//  Created by City--Online on 15/10/30.
//  Copyright  2015年 City--Online. All rights reserved.
//

#import "DetailView.h"

static const int columns=4;
static const float rowHeight=30.0;
//static const int rows=2;
@interface DetailView ()<UICollectionViewDelegate,UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>

@property (nonatomic,strong) UICollectionView *collectionView;

@property (nonatomic,strong) NSArray *titleArray;
@end

@implementation DetailView

- (instancetype)initWithFrame:(CGRect)frame withTitleArray:(NSArray *)titleArray
{
    _titleArray=titleArray;
    return [self initWithFrame:frame];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {

        UICollectionViewFlowLayout  *collectionViewFlowLayout=[[UICollectionViewFlowLayout alloc]init];
        collectionViewFlowLayout.minimumInteritemSpacing=0.0;
        collectionViewFlowLayout.minimumLineSpacing=0.0;
        collectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
        collectionViewFlowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0, 0, 0.0);

        float columuWidth=self.bounds.size.width/columns;
        collectionViewFlowLayout.itemSize=CGSizeMake(columuWidth, rowHeight);
        collectionViewFlowLayout.estimatedItemSize=CGSizeMake(columuWidth, rowHeight);

        collectionViewFlowLayout.scrollDirection=UICollectionViewScrollDirectionVertical;

        collectionViewFlowLayout.headerReferenceSize=CGSizeMake(0, 0);
        collectionViewFlowLayout.footerReferenceSize=CGSizeMake(0, 0);

        _collectionView=[[UICollectionView alloc]initWithFrame:self.bounds collectionViewLayout:collectionViewFlowLayout];
        _collectionView.backgroundColor=[UIColor whiteColor];
        _collectionView.delegate=self;
        _collectionView.dataSource=self;
        _collectionView.allowsSelection=YES;
//        _collectionView.allowsMultipleSelection=YES;

        [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
        [self addSubview:_collectionView];
    }
    return self;
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return _titleArray.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell =[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor colorWithRed:arc4random()%256/ 255.0  green:arc4random()%256 / 255.0 blue:arc4random()% 256 / 255.0  alpha:1];
    return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    if (self.detailIndexPathBlock != nil) {
        self.detailIndexPathBlock(indexPath);
    }
}

@end

3.主视图

//
//  MainView.h
//  Spread
//
//  Created by City--Online on 15/10/30.
//  Copyright  2015年 City--Online. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface MainView : UIView

- (instancetype)initWithFrame:(CGRect)frame withTitleArray:(NSArray *)mainArray;

@end

//
//  MainView.m
//  Spread
//
//  Created by City--Online on 15/10/30.
//  Copyright  2015年 City--Online. All rights reserved.
//

#import "MainView.h"
#import "DetailView.h"

static const int columns=4;

@interface MainView ()<UICollectionViewDataSource,UIBarPositioningDelegate,UICollectionViewDelegateFlowLayout>

@property (nonatomic,strong) UICollectionView *collectionView;

@property (nonatomic,strong) NSArray *mainArray;

@property (nonatomic,strong) NSMutableArray *detailArray;

@property (nonatomic,strong) NSIndexPath *selectIndexPath;

@property (nonatomic,strong) DetailView *detailView;

@property (nonatomic,assign) bool    *IsSpread;

@end

@implementation MainView

- (instancetype)initWithFrame:(CGRect)frame withTitleArray:(NSArray *)mainArray
{
    _mainArray=mainArray;
    _selectIndexPath=nil;
    return [self initWithFrame:frame];
}
- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        UICollectionViewFlowLayout  *collectionViewFlowLayout=[[UICollectionViewFlowLayout alloc]init];
        collectionViewFlowLayout.minimumInteritemSpacing=1.0;
        collectionViewFlowLayout.minimumLineSpacing=0.0;
        collectionViewFlowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
        collectionViewFlowLayout.sectionInset = UIEdgeInsetsMake(0.0, 0.0, 0, 0.0);
        float columuWidth=(self.bounds.size.width-columns+1)/columns;
        collectionViewFlowLayout.itemSize=CGSizeMake(columuWidth, columuWidth);
        collectionViewFlowLayout.estimatedItemSize=CGSizeMake(columuWidth, columuWidth);
        collectionViewFlowLayout.scrollDirection=UICollectionViewScrollDirectionVertical;
        collectionViewFlowLayout.headerReferenceSize=CGSizeMake(0, 0);
        collectionViewFlowLayout.footerReferenceSize=CGSizeMake(0, 0);
        _collectionView=[[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:collectionViewFlowLayout];
        _collectionView.backgroundColor=[UIColor whiteColor];
        _collectionView.delegate=self;
        _collectionView.dataSource=self;
        _collectionView.allowsSelection=YES;
        [_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
        [_collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:@"footer"];
        [self addSubview:_collectionView];
    }
    return self;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return columns;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell =[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];

    cell.backgroundColor=indexPath.section%2? [UIColor redColor]:[UIColor yellowColor];
    if (indexPath.section*columns+indexPath.row>_mainArray.count) {
        cell.backgroundColor=[UIColor clearColor];
    }
    return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{

    if (_selectIndexPath!=indexPath&&_selectIndexPath!=nil) {
        _IsSpread=YES;
    }
    else
    {
        _IsSpread=!_IsSpread;
    }

    if (!_IsSpread) {
        //改变主CollectionView视图Frame和子CollectionView的Frame
        self.frame=CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.width);
    }
    else
    {
        self.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.width+((int)(_detailArray.count+3)/4)*30.0);
    }

    _collectionView.frame = self.frame;
    _selectIndexPath=indexPath;
    //改变数据源
     _detailArray=[(@[@"AAA",@"BBB",@"CCC",@"DDD",@"EEE"]) mutableCopy];
    [_collectionView reloadData];

}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return (_mainArray.count+columns-1)/4;
}
//针对每个分区的页眉和页脚, 返回对应的视图对象, 重用的
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{

    UICollectionReusableView *footerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"footer" forIndexPath:indexPath];

    //将第二个视图控制器添加到区尾上
    if (_detailView!=nil) {
        [_detailView removeFromSuperview];
        _detailView=nil;
    }
    _detailView =[[DetailView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, ((int)(5+3)/4)*30.0) withTitleArray:_detailArray];
    _detailView.detailIndexPathBlock=^(NSIndexPath *indexPath)
    {
        NSLog(@"%@",indexPath);
    };
    [footerView addSubview:_detailView];

    return footerView;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section
{
    if (section==_selectIndexPath.section&&_IsSpread) {
        return CGSizeMake(self.bounds.size.width, ((int)(_detailArray.count+3)/4)*30.0) ;
    }
    else
    {
        return CGSizeZero;
    }
}
@end

4.调用

//
//  ViewController.m
//  Spread
//
//  Created by City--Online on 15/10/30.
//  Copyright  2015年 City--Online. All rights reserved.
//

#import "ViewController.h"
#import "MainView.h"
#import "DetailView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    MainView *mainView=[[MainView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width) withTitleArray:@[@"1",@"2",@"3",@"4",@"5",@"6"]];
    [self.view addSubview:mainView];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

5.结果图

 今天又添加了ScrollView分页 demo地址:https://github.com/ywcui/Spread

时间: 2024-09-27 06:29:10

UICollectionView二级树展开的相关文章

[老贴重发]EXT:指定树控件TreePanel 展开到第几层

12年写的文章了,可能由于某博客某年帐号泄露,被人删除了很多文章. 还有底搞的,我就重发一下. 对于Ext.tree.TreePanel,相信使用过EXT的人一般都用到过.所以本文中不会包含EXT或TreePanel 基础知识的介绍了      比如做一个行政区划的树.如下图所示: 但在有的时候,这颗树的数据量会很大,层级也会很深,默认全部展开的话,会很慢,而且显示一大堆东西出来,显示不符合用户的需求.可又不是默认全部折叠,这样用户又第一眼看不见想关心的东西的内容.     所以笔者在这里提出了

用jquery做的向下滑动导航条,页面刷新后怎样使导航条展开状态为我刷新前点击的状态

问题描述 问题如上.我在网上找了一个jquery导航,点击第一层菜单可以滑动展开二层菜单,初始状态为定义一个一级菜单的二级菜单展开,其他的一级菜单的二层菜单都是隐藏的,那么当我点击第二个一级菜单的二级菜单时,页面刷新后,又回到初始状态了(第一个一级菜单展开,其他的隐藏),我怎样让刷新后的状态上一次展开的状态. 解决方案 解决方案二:每次展开后在document.cookie中记录当前展开的位置,在$()中写一个检测到有记录则展开该位置的函数

精心收集的jQuery常用的插件1000_jquery

1.accordion类 基于jQuery开发,非常简单的水平方向折叠控件. Horizontal accordion: jQuery 热点图书:www.hotbook.cn jQuery-Horizontal Accordion 具有XBOX360 blade界面风格的水平方向Accordion. jQuery-Horizontal Accordion jQuery plugin: Accordion 用于创建 折叠菜单的jQuery插件. jQuery plugin: Accordion 热

Android TreeView效果实现方法(附demo源码下载)_Android

本文实例讲述了Android TreeView效果实现方法.分享给大家供大家参考,具体如下: 应该说很多的操作系统上面都提供了TreeView空间,实现树形结构,这个树形结构的应用时很广泛的,而Google开发Android的时候出于Android手机是触摸屏幕的考虑,用手指操作树形结构很不方便,从这方面考虑没有提供TreeView的空间,而是只是提供了一个ExpandableListView:android中的二级树型Widget,虽然已经能满足不少的功能需求,例如书签的功能就可以使用这个控件

jQuery:收集一些基于jQuery框架开发的控件/jquery插件2

Horizontal accordion: jQuery基于jQuery开发,非常简单的水平方向折叠控件.主页:http://letmehaveblog.blogspot.com/2007/10/haccordion-simple-horizontal-accordion.html (无法找到)下载:http://letmehaveblog.blogspot.com/2007/10/haccordion-simple-horizontal-accordion.html 示例:http://let

超强1000个jquery插件!

1.导航类 (1)Horizontal accordion: jQuery 基于jQuery开发,非常简单的水平方向折叠控件. 二手图书 二手书 特价书 旧书网 (2)jQuery-Horizontal Accordion 具有XBOX360 blade界面风格的水平方向Accordion. 二手图书 二手书 特价书 旧书网 (3)jQuery plugin: Accordion 用于创建 折叠菜单的jQuery插件.二手图书 二手书 特价书 旧书网 (4)Accordion Menu scri

Android TreeView效果实现方法(附demo源码下载)

本文实例讲述了Android TreeView效果实现方法.分享给大家供大家参考,具体如下: 应该说很多的操作系统上面都提供了TreeView空间,实现树形结构,这个树形结构的应用时很广泛的,而Google开发Android的时候出于Android手机是触摸屏幕的考虑,用手指操作树形结构很不方便,从这方面考虑没有提供TreeView的空间,而是只是提供了一个ExpandableListView:android中的二级树型Widget,虽然已经能满足不少的功能需求,例如书签的功能就可以使用这个控件

网站改版案例分析:印像派首页改版视觉效果分析

文章描述:浅谈印像派首页改版之视觉篇 . . . . 前段时间在做印像派的全站改版,其中包括首页.列表页.详情页.主题页等页面,整个项目历时较久.前段时间新版印像派上线了,首页初稿由葱头同学设计定稿的,后期由我跟进优化,现在正好以印像派首页为切入点做个设计回顾. . 网易印像派(yxp.163.com)是网易公司推出的个性产品服务平台,在网易印像派可以网上冲印各类数码产品.随着印像派业务不断扩展,几年前设计的首页无论是在交互还是视觉上都已经无法满足现有的业务需求,所以首页的改版是一件迟早要提上议

跨进程实现在Tree中快速定位节点

进程     前些日子写软件时,需要实现一个功能,就是在Tree中快速定位节点,比如注册表编辑器左边的Tree,只要给出Tree中的节点路径(以"\"分隔),就可以快速将树展开,并将当前节点定位到指定的节点.功能的实现并不难,但稍有些麻烦.原因在于,如果是本进程中的Tree,只要发消息就可以了,但如果是另外一个进程中的Tree,就要在那个进程中申请内存,将Tree节点的文字复制到这块内存,然后再把这块内存的数据复制到本进程的一块内存中,才能与指定的节点路径相比较.由于这个功能还有一些可