【iOS】UICollectionView自己定义Layout之蜂窝布局

网上的UICollectionView的Layout布局,其cell的形状多为矩形和圆形。

本篇博文将正六边形作为cell的基本形状,为您展现独特的蜂窝布局效果及实现源代码。

帮助您让自己的App脱颖而出,更加与众不同。

最新完整代码下载地址:https://github.com/duzixi/Varied-Layouts

博文首发地址:http://blog.csdn.net/duzixi

实现效果图:

核心源码:

自己定义Layout

//
//  HoneyCombLayout.h
//  Demo-Layouts
//
//  Created by 杜子兮(duzixi) on 14-9-1.
//  Copyright (c) 2014年 lanou3g.com All rights reserved.
//

#import <UIKit/UIKit.h>

@interface HoneyCombLayout : UICollectionViewLayout

@property (nonatomic, assign) NSInteger margin;
@property (nonatomic, assign) NSInteger oX;
@property (nonatomic, assign) NSInteger oY;

@end
//
//  HoneyCombLayout.m
//  Demo-Layouts
//
//  Created by 杜子兮(duzixi) on 14-9-1.
//  Copyright (c) 2014年 lanou3g.com All rights reserved.
//

#import "HoneyCombLayout.h"

@implementation HoneyCombLayout

///  返回内容大小。用于推断是否须要加快滑动

-(CGSize)collectionViewContentSize
{
    float height = (SIZE + self.margin) * ([self.collectionView numberOfItemsInSection:0] / 4 + 1);
    return CGSizeMake(320, height);
}

///  返回YES,改变布局
/*
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
    return YES;
}
*/
#pragma mark - UICollectionViewLayout
///  为每个Item生成布局特性
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

    UICollectionView *collection = self.collectionView;

    float x = (SIZE + self.margin) * (indexPath.item % COL + 1) * 0.75;
    float y = (SIZE + self.margin) * (indexPath.item / COL + 0.5) * cos(M_PI * 30.0f / 180.0f);
    if (indexPath.item % 2 == 1) {
        y += (SIZE + self.margin) * 0.5 * cosf(M_PI * 30.0f / 180.0f);
    }

    x += self.oX;
    y += self.oY;

    attributes.center = CGPointMake(x + collection.contentOffset.x, y + collection.contentOffset.y);
    attributes.size = CGSizeMake(SIZE, SIZE * cos(M_PI * 30.0f / 180.0f));

    return attributes;
}

-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *arr = [super layoutAttributesForElementsInRect:rect];
    if ([arr count] > 0) {
        return arr;
    }
    NSMutableArray *attributes = [NSMutableArray array];
    for (NSInteger i = 0 ; i < [self.collectionView numberOfItemsInSection:0 ]; i++) {
        NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        [attributes addObject:[self layoutAttributesForItemAtIndexPath:indexPath]];
    }
    return attributes;
}

@end

自己定义cell:

//
//  HoneycombViewCell.h
//  Demo-Layouts
//
//  Created by 杜子兮(duzixi) on 14-9-1.
//  Copyright (c) 2014年 lanou3g.com All rights reserved.
//

#import <UIKit/UIKit.h>

@interface HoneycombViewCell : UICollectionViewCell

@property (nonatomic,strong) UILabel *titleLabel;

@end
//
//  HoneycombViewCell.m
//  Demo-Layouts
//
//  Created by 杜子兮(duzixi) on 14-9-1.
//  Copyright (c) 2014年 lanou3g.com All rights reserved.
//

#import "HoneycombViewCell.h"

@implementation HoneycombViewCell

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.titleLabel = [[UILabel alloc] init];
        self.titleLabel.textColor = [UIColor whiteColor];
        [self.contentView addSubview:self.titleLabel];
    }
    return self;
}

-(void)layoutSubviews
{
    [super layoutSubviews];
    // step 1: 生成六边形路径
    CGFloat longSide = SIZE * 0.5 * cosf(M_PI * 30 / 180);
    CGFloat shortSide = SIZE * 0.5 * sin(M_PI * 30 / 180);
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, longSide)];
    [path addLineToPoint:CGPointMake(shortSide, 0)];
    [path addLineToPoint:CGPointMake(shortSide + SIZE * 0.5, 0)];
    [path addLineToPoint:CGPointMake(SIZE, longSide)];
    [path addLineToPoint:CGPointMake(shortSide + SIZE * 0.5, longSide * 2)];
    [path addLineToPoint:CGPointMake(shortSide, longSide * 2)];
    [path closePath];

    // step 2: 依据路径生成蒙板
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.path = [path CGPath];

    // step 3: 给cell加入模版
    self.layer.mask = maskLayer;

    self.backgroundColor = [UIColor orangeColor];
    self.titleLabel.textAlignment = NSTextAlignmentCenter;
    self.titleLabel.frame = self.contentView.frame;

}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
    // Drawing code
}
*/

@end
时间: 2024-12-06 22:08:02

【iOS】UICollectionView自己定义Layout之蜂窝布局的相关文章

UICollectionView自定义Layout之蜂窝布局

网上的UICollectionView的Layout布局,其cell的形状多为矩形和圆形. 本篇博文将正六边形作为cell的基本形状,为您展现独特的蜂窝布局效果及实现源码. 帮助您让自己的App脱颖而出,更加与众不同. 最新完整代码下载地址:https://github.com/duzixi/Varied-Layouts 博文首发地址:http://blog.csdn.net/duzixi 实现效果图: 核心源代码: 自定义Layout // // HoneyCombLayout.h // De

iOS开发之Auto Layout入门

随着iPhone6与iOS8的临近,适配的问题讲更加复杂,最近学习了一下Auto Layout的使用,与大家分享.  什么是Auto Layout? Auto Layout是iOS6发布后引入的一个全新的布局特性,其目的是弥补以往Autoresizing在布局方面的不足之处,以及未来面对更多尺寸适配时界面布局可以更好的适应. 为什么要用Auto Layout? Autolayout能解决不同屏幕(iPhone4,iPhone5,iPad...)之间的适配问题. 在iPhone4时代开发者只需要适

IOS开发UI篇--UITableView的自定义布局==纯代码布局

UITableView中除了利用系统的UItableViewCell不能完成需求进行布局时,还可以进行自定义布局: 自定义布局分为两类:(1)利用代码进行创建 (2)利用xib进行实现: 下面对利用代码进行创建分析: 应用场景:像微博,等列表数据展示(由于微博的每个单元格的数据大小不一致,所以得计算每个单元格的大小) 分析:前提是获取列表数据,然后建立每个单元格的模型(建立单元格模型应继承UITableViewCell)复写 - (id)initWithStyle:(UITableViewCel

iOS UICollectionView 入门 01 简介

当第一代ipad发布时,相册程序相当吸引眼球,它以独特的方式以多样的布局来显示照片,可以使扁平的表格view: 也可以是有层次的按分类进行查看: 还可以使用手势,以很炫的方式在不同的布局之间进行切换.我们可以使用gridview和一些其它的布局来实现这些,但是太麻烦了,从iOS6开始,我们可以使用UICollectionView来实现它,我们可以很容易的为程序添加自定义布局和自定义转换. UICollectionViewController解析 我们通过一个示例图,来看看UICollection

iOS重用宏定义

iOS 多快好省的宏(转) 原文地址:http://my.oschina.net/yongbin45/blog/150149 // 字符串: #ifndef nilToEmpty #define nilToEmpty(object) (object!=nil)?object:@"" #endif #ifndef formatStringOfObject #define formatStringOfObject(object) [NSString stringWithFormat:@&q

iOS之宏定义#define

最基本的宏定义用法 #define aaa  bbb 表示用aaa替换bbb的内容. 宏作用范围 宏的作用范围是在当前文件内, 如果需要作用于其他类(如在类b调用类a已定义宏),那么需要在类b引入类a的头文件(a.h). 如果需要作用于整个工程,可以定义一个类如Config.h,在该类定义好需要的宏,然后在工程的XXX_Prefix.pch文件 #import "Config.h" 在Config.h中 #define aaa  bbb 在XXX_Prefix.pch文件 中 #ifd

iOS UICollectionView与UITableView

共同点:都需要接受两个协议 并执行代理方法 不同点:初始化方法不同  UITableVIew可以用alloc 方法初始化 而UICollectionView必须用下面方法初始化 // 初始化瀑布流 UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; [flowLayout setItemSize:CGSizeMake(150,120)]; //设置每个cell显示数据的宽和高必须

IOS开发UI篇--UITableView的自定义布局==xib布局

利用Xib进行实现 应用场景:像团购网站的列表数据显示,新闻列表显示等(由于该类的显示的数据单元格内容格式相同) (1)主控制器文件,在文件中实现了自己自定义的代理,加载数据, 1 #import "SLViewController.h" 2 #import "SLTgDatas.h" 3 #import "SLTableViewCell.h" 4 #import "SLFooterView.h" 5 #import &quo

iOS 使用宏定义函数和代码块

iOS使用宏定义函数和代码块 今天在开发过程中碰到一个问题:就是父类中要向外发送通知,然后子类中或者其他类中来接收它.当然一般是把它写到类方法中去,但是有个问题,就是如果调用的类不是它的子类,就不能直接调用,当然也可以采用静态方法实现,我这里主要是想用宏定义来实现,下面我分别介绍使用宏定义函数和定义代码块的方式进行,废话不多说了,直接上代码: 使用宏定义函数实现 //定义 #define SendNotification @"SendNotification" #define send