首页 > 移动平台 > 详细

IOS UI-自定义UIColectionView布局

时间:2016-02-27 20:39:26      阅读:191      评论:0      收藏:0      [点我收藏+]

ViewController.m

 1 //
 2 //  ViewController.m
 3 //  IOS_0226_自定义UIColectionView布局
 4 //
 5 //  Created by ma c on 16/2/26.
 6 //  Copyright © 2016年 博文科技. All rights reserved.
 7 //
 8 
 9 #import "ViewController.h"
10 #import "ImgCell.h"
11 #import "LineLayout.h"
12 #import "FoldLayout.h"
13 #import "CircleLayout.h"
14 
15 
16 @interface ViewController ()<UICollectionViewDataSource,UICollectionViewDelegate>
17 
18 @property (nonatomic, strong) NSMutableArray *imgsArray;
19 @property (nonatomic, weak) UICollectionView *collectionView;
20 
21 @end
22 
23 @implementation ViewController
24 
25 static NSString *ID = @"image";
26 
27 - (NSMutableArray *)imgsArray
28 {
29     if (!_imgsArray) {
30         _imgsArray = [NSMutableArray array];
31         
32         for (int i=1; i<9; i++) {
33             [_imgsArray addObject:[NSString stringWithFormat:@"%d.jpg",i]];
34             
35         }
36     }
37     return _imgsArray;
38 }
39 
40 - (void)viewDidLoad {
41     [super viewDidLoad];
42     [self createUI];
43 }
44 
45 - (void)createUI
46 {
47     CGRect rect = CGRectMake(7, 100, 400, 200);
48     UICollectionView *collection = [[UICollectionView alloc] initWithFrame:rect collectionViewLayout:[[FoldLayout alloc] init]];
49     collection.dataSource = self;
50     collection.delegate = self;
51 //    [collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:ID];
52     [collection registerNib:[UINib nibWithNibName:@"ImgCell" bundle:nil] forCellWithReuseIdentifier:ID];
53     [self.view addSubview:collection];
54     self.collectionView = collection;
55 
56     
57 }
58 
59 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
60 {
61     if ([self.collectionView.collectionViewLayout isKindOfClass:[FoldLayout class]]) {
62         [self.collectionView setCollectionViewLayout:[[CircleLayout alloc] init] animated:YES];
63     }
64     else{
65         [self.collectionView setCollectionViewLayout:[[FoldLayout alloc] init] animated:YES];
66     }
67 }
68 
69 #pragma mark - UICollectionViewDataSource
70 
71 - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
72 {
73     return self.imgsArray.count;
74 }
75 
76 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
77 {
78     ImgCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
79     
80     cell.image = self.imgsArray[indexPath.item];
81     
82     return cell;
83 }
84 
85 #pragma mark - UICollectionViewDelegate
86 
87 - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
88 {
89     //删除模型数据
90     [self.imgsArray removeObjectAtIndex:indexPath.item];
91     //刷新UI
92     [collectionView deleteItemsAtIndexPaths:@[indexPath]];
93 }
94 
95 @end

LineLayout.m(线性流水布局)
  1 //
  2 //  LineLayout.m
  3 //  IOS_0226_自定义UIColectionView布局
  4 //
  5 //  Created by ma c on 16/2/26.
  6 //  Copyright © 2016年 博文科技. All rights reserved.
  7 //
  8 
  9 #import "LineLayout.h"
 10 
 11 static const CGFloat lineLayoutSize = 100;
 12 
 13 @implementation LineLayout
 14 
 15 
 16 //初始化
 17 - (void)prepareLayout
 18 {
 19     [super prepareLayout];
 20     //设置item大小
 21     self.itemSize = CGSizeMake(lineLayoutSize, lineLayoutSize);
 22     //设置两端居中
 23     CGFloat inset = (self.collectionView.frame.size.width - lineLayoutSize) * 0.5;
 24     self.sectionInset = UIEdgeInsetsMake(0, inset, 0, inset);
 25     
 26     //设置水平滚动
 27     self.scrollDirection = UICollectionViewScrollDirectionHorizontal;
 28     //设置间距
 29     self.minimumLineSpacing = lineLayoutSize;
 30     
 31 
 32     
 33     //每一个item都有自己的UICollectionViewLayoutAttributes
 34     //每一indexPath都有自己的UICollectionViewLayoutAttributes
 35 }
 36 
 37 //只要显示的边界发生变化就重新布局:内部会重新调用prepareLayout,layoutAttributesForElementsInRect方法获得所有item的布局属性
 38 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
 39 {
 40     return YES;
 41 }
 42 
 43 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
 44 {
 45     //NSLog(@"layoutAttributesForElementsInRect");
 46     // 0.计算可见的矩形框
 47     CGRect visibleRect;
 48     visibleRect.size = self.collectionView.frame.size;
 49     visibleRect.origin = self.collectionView.contentOffset;
 50     // 1.获得默认的item的UICollectionViewLayoutAttributes
 51     NSArray *array = [super layoutAttributesForElementsInRect:rect];
 52     NSArray * attributes = [[NSArray alloc] initWithArray:array copyItems:YES];
 53 
 54     
 55     // 2.计算屏幕最中间的x
 56     CGFloat centerX = self.collectionView.contentOffset.x + self.collectionView.frame.size.width * 0.5;
 57     
 58     for (UICollectionViewLayoutAttributes *attr in attributes) {
 59         
 60         if (!CGRectIntersectsRect(visibleRect, attr.frame))  continue;
 61         
 62         // 每一个item中点x
 63         CGFloat itemCenterX = attr.center.x;
 64         //计算item离屏幕中间的距离
 65         CGFloat distance = ABS(itemCenterX - centerX);
 66         //距离越小,缩放比例越大
 67         CGFloat zoom = 1 - (distance / (self.collectionView.frame.size.width * 0.5));
 68         //NSLog(@"%f",zoom);
 69         //缩放比例
 70         CGFloat scale = 1 + 0.5 * zoom;
 71         //缩放
 72         attr.transform3D = CATransform3DMakeScale(scale, scale, 1);
 73     }
 74     
 75     return attributes;
 76 }
 77 
 78 //用来设置UICollectionView停止滚动那一刻的位置
 79 - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
 80 {
 81     // 1.计算UICollectionView最终停止的范围
 82     CGRect lastRect;
 83     lastRect.origin = proposedContentOffset;
 84     lastRect.size = self.collectionView.frame.size;
 85     // 计算屏幕中间的x
 86     CGFloat centerX = proposedContentOffset.x + self.collectionView.frame.size.width * 0.5;
 87     // 2.取出这个范围内的所有属性
 88     NSArray *array = [super layoutAttributesForElementsInRect:lastRect];
 89     NSArray * attributes = [[NSArray alloc] initWithArray:array copyItems:YES];
 90     
 91     
 92     // 3.遍历所有属性
 93     CGFloat adjustOffsetX = MAXFLOAT;
 94     for (UICollectionViewLayoutAttributes *attr in attributes) {
 95         if (ABS(attr.center.x - centerX) < ABS(adjustOffsetX)) {
 96             adjustOffsetX = attr.center.x - centerX;
 97         }
 98     }
 99     return CGPointMake(proposedContentOffset.x + adjustOffsetX, proposedContentOffset.y);
100 }
101 
102 @end

FoldLayout.m(折叠布局)

 1 //
 2 //  FoldLayout.m
 3 //  IOS_0226_自定义UIColectionView布局
 4 //
 5 //  Created by ma c on 16/2/27.
 6 //  Copyright © 2016年 博文科技. All rights reserved.
 7 //
 8 
 9 #import "FoldLayout.h"
10 
11 #define Random0_1 (arc4random_uniform(100)/100)
12 
13 @implementation FoldLayout
14 
15 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
16 {
17     return YES;
18 }
19 
20 - (CGSize)collectionViewContentSize
21 {
22     return CGSizeMake(500, 500);
23 }
24 
25 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
26 {
27     NSArray *angles = @[@0, @(-0.2), @(-0.5), @0, @(0.2), @(0.5)];
28     
29     UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
30     attrs.size = CGSizeMake(100, 100);
31     //        attrs.center = CGPointMake(arc4random_uniform(self.collectionView.frame.size.width), arc4random_uniform(self.collectionView.frame.size.height));
32     attrs.center = CGPointMake(self.collectionView.frame.size.width * 0.5, self.collectionView.frame.size.height * 0.5);
33     if (indexPath.item >= 6) {
34         attrs.hidden = YES;
35     } else {
36         attrs.transform = CGAffineTransformMakeRotation([angles[indexPath.item] floatValue]);
37         //zIndex越大,就越在上面
38         attrs.zIndex = [self.collectionView numberOfItemsInSection:indexPath.section] - indexPath.item;
39     }
40     return attrs;
41 }
42 
43 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
44 {
45     NSMutableArray *array = [NSMutableArray array];
46     NSInteger count = [self.collectionView numberOfItemsInSection:0];
47     
48     for (int i=0; i<count; i++) {
49 //        UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:[NSIndexPath indexPathForItem:i inSection:0]];
50 //        attrs.size = CGSizeMake(100, 100);
51 //        attrs.center = CGPointMake(self.collectionView.frame.size.width * 0.5, self.collectionView.frame.size.height * 0.5);
52 //        if (i >= 5) {
53 //            attrs.hidden = YES;
54 //        } else {
55 //            
56 //            NSArray *angles = @[@0, @(-0.2), @(-0.5), @(0.2), @(0.5)];
57 //            attrs.transform = CGAffineTransformMakeRotation([angles[i] floatValue]);
58 //            //zIndex越大,就越在上面
59 //            attrs.zIndex = count - i;
60         NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
61         UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
62         [array addObject:attrs];
63         
64         }
65     return array;
66 }
67     
68 
69 @end
CircleLayout.m(环形布局)
 1 //
 2 //  CircleLayout.m
 3 //  IOS_0226_自定义UIColectionView布局
 4 //
 5 //  Created by ma c on 16/2/27.
 6 //  Copyright © 2016年 博文科技. All rights reserved.
 7 //
 8 
 9 #import "CircleLayout.h"
10 
11 @implementation CircleLayout
12 
13 - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
14 {
15     return YES;
16 }
17 
18 - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
19 {
20     
21     UICollectionViewLayoutAttributes *attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
22     attrs.size = CGSizeMake(50, 50);
23     
24     //圆的半径
25     CGFloat radius = 70;
26     CGPoint cireclecenter = CGPointMake(self.collectionView.frame.size.width * 0.5, self.collectionView.frame.size.height * 0.5);
27     //每个item间角度
28     CGFloat angleDetla = M_PI * 2 / [self.collectionView numberOfItemsInSection:indexPath.section];
29     
30     //计算当前item角度
31     CGFloat angle = indexPath.item * angleDetla;
32     attrs.center = CGPointMake(cireclecenter.x + radius * cosf(angle), cireclecenter.y + radius * sinf(angle));
33     
34     attrs.zIndex = indexPath.item;
35     return attrs;
36 }
37 
38 - (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
39 {
40     NSMutableArray *array = [NSMutableArray array];
41     NSInteger count = [self.collectionView numberOfItemsInSection:0];
42     
43     for (int i=0; i<count; i++) {
44         NSIndexPath *indexPath = [NSIndexPath indexPathForItem:i inSection:0];
45         UICollectionViewLayoutAttributes *attrs = [self layoutAttributesForItemAtIndexPath:indexPath];
46         [array addObject:attrs];
47         
48     }
49     return array;
50 }
51 
52 @end
ImgCell.h(自定义UICollectionViewCell)
 1 //
 2 //  ImgCell.h
 3 //  IOS_0226_自定义UIColectionView布局
 4 //
 5 //  Created by ma c on 16/2/26.
 6 //  Copyright © 2016年 博文科技. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface ImgCell : UICollectionViewCell
12 
13 @property (weak, nonatomic) IBOutlet UIImageView *imgView;
14 @property (nonatomic, copy) NSString *image;
15 
16 
17 @end
18 
19 
20 //
21 //  ImgCell.m
22 //  IOS_0226_自定义UIColectionView布局
23 //
24 //  Created by ma c on 16/2/26.
25 //  Copyright © 2016年 博文科技. All rights reserved.
26 //
27 
28 #import "ImgCell.h"
29 
30 @interface ImgCell ()
31 
32 @end
33 
34 @implementation ImgCell
35 
36 - (void)setImage:(NSString *)image
37 {
38     _image = [image copy];
39     self.imgView.image = [UIImage imageNamed:_image];
40 }
41 
42 - (void)awakeFromNib {
43     self.imgView.layer.borderWidth = 3;
44     self.imgView.layer.borderColor = [UIColor whiteColor].CGColor;
45     self.imgView.layer.cornerRadius = 5;
46     self.imgView.clipsToBounds = YES;
47 }
48 
49 @end

 

IOS UI-自定义UIColectionView布局

原文:http://www.cnblogs.com/oc-bowen/p/5223494.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!