博客> 一个UICollectionView自定义layout的实现
一个UICollectionView自定义layout的实现
2017-12-12 18:52 评论:0 阅读:429 诸葛亮倒骑小毛驴
ios 一个UICollectionView自定义layout的实现

一个UICollectionView自定义layout的实现

import

@interface AppDelegate : UIResponder

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) NSMutableArray *letterArray;

@end

import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

  • (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions { self.letterArray = [NSMutableArray array]; for(int i=0; i<26>

@interface ViewController : UIViewController

@end

import "ViewController.h"

import "AppDelegate.h"

import "CollectionViewDataSource.h"

import "DraggableCircleLayout.h"

import "LSCollectionViewHelper.h"

@interface ViewController () { UICollectionView collectionView; CollectionViewDataSource cvDataSource; } @end

@implementation ViewController

  • (IBAction)ChangeLayoutClickHandler:(id)sender { if([collectionView.collectionViewLayout isKindOfClass:[CircleLayout class]]) { UICollectionViewFlowLayout layout = [[UICollectionViewFlowLayout alloc] init]; collectionView.collectionViewLayout = layout; } else { CircleLayout layout = [[CircleLayout alloc] init]; collectionView.collectionViewLayout = layout; } }

  • (IBAction)BatchUploadClickHandler:(id)sender { //这里有个细节需要注意,最好是将删除操作放在添加操作前面,因为无论你顺序如何,始终都会先执行删除操作。 //如果代码顺序是先添加后删除,但实际执行顺序是先删除后添加,可能会因为索引不对影响代码逻辑。 [collectionView performBatchUpdates:^{ NSMutableArray letterArray = [self getLetterArray]; //删除四个元素 NSIndexPath path1 = [NSIndexPath indexPathForItem:0 inSection:0]; NSIndexPath path2 = [NSIndexPath indexPathForItem:1 inSection:0]; NSIndexPath path3 = [NSIndexPath indexPathForItem:2 inSection:0]; NSIndexPath *path4 = [NSIndexPath indexPathForItem:3 inSection:0];

    NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0,4)];
    
    [indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop){
        NSLog(@"%lu", (unsigned long)idx);
    }];
    
    [letterArray removeObjectsAtIndexes:indexSet];
    
    NSArray *array = [NSArray arrayWithObjects:path1, path2, path3, path4, nil];
    [collectionView deleteItemsAtIndexPaths:array];
    
    //添加一个元素
    [letterArray addObject:@"1"];
    
    [collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:letterArray.count-1 inSection:0]]];

    } completion:nil]; }

  • (void)viewDidLoad { [super viewDidLoad];

// UICollectionViewFlowLayout layout = [[UICollectionViewFlowLayout alloc] init]; // CircleLayout layout = [[CircleLayout alloc] init]; DraggableCircleLayout *layout = [[DraggableCircleLayout alloc] init];

collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(10, 50, 300, 400) collectionViewLayout:layout];

collectionView.backgroundColor = [UIColor grayColor];
collectionView.draggable = YES;

[collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"LetterCell"];
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:@"FirstSupplementary" withReuseIdentifier:@"ReuseID"];
[collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:@"SecondSupplementary" withReuseIdentifier:@"ReuseID"];   

cvDataSource = [CollectionViewDataSource alloc];
collectionView.dataSource = cvDataSource;
collectionView.delegate = cvDataSource;

[self.view addSubview:collectionView];

UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHandler:)];
[collectionView addGestureRecognizer:tapRecognizer];

}

  • (void)tapGestureHandler:(UITapGestureRecognizer )sender { CGPoint point = [sender locationInView:collectionView]; NSIndexPath tappedCellPath = [collectionView indexPathForItemAtPoint:point];

    NSMutableArray letterArray = [self getLetterArray]; if(tappedCellPath) { //删除点击的cell [letterArray removeObjectAtIndex:tappedCellPath.item]; [collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:tappedCellPath]]; } else { //如果点击空白处,在末尾添加一个随机小写字母 unichar asciiX = (unichar)[self getRandomNumber:97 to:97+26]; [letterArray addObject:[NSString stringWithFormat:@"%C",asciiX]]; NSIndexPath path = [NSIndexPath indexPathForItem:letterArray.count-1 inSection:0]; [collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:path]]; } }

  • (NSMutableArray )getLetterArray { AppDelegate appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    return appDelegate.letterArray; }

  • (int)getRandomNumber:(int)from to:(int)to { return (int)(from + (arc4random() % (to-from))); }

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

@end

import

import "UICollectionView+Draggable.h"

@interface CollectionViewDataSource : NSObject

@end

import

import "AppDelegate.h"

import "CollectionViewDataSource.h"

@implementation CollectionViewDataSource

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

  • (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { return [self getLetterArray].count; }

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

    //先移除可重用cell里面的子元素(否则会出现新旧交叠) [cell.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

    cell.backgroundColor = [UIColor yellowColor];

    UILabel *label = [[UILabel alloc] init]; label.text = [[self getLetterArray] objectAtIndex:indexPath.row]; label.font = [UIFont systemFontOfSize:12]; [label sizeToFit]; label.center = CGPointMake(cell.bounds.size.width/2, cell.bounds.size.height/2); [cell addSubview:label];

    return cell; }

  • (UICollectionReusableView )collectionView:(UICollectionView )collectionView viewForSupplementaryElementOfKind:(NSString )kind atIndexPath:(NSIndexPath )indexPath { UICollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"ReuseID" forIndexPath:indexPath];

    view.backgroundColor = [UIColor greenColor];

    UILabel *label = [[UILabel alloc] init]; label.text = kind; label.font = [UIFont systemFontOfSize:24]; [label sizeToFit]; label.center = CGPointMake(view.bounds.size.width/2, view.bounds.size.height/2); [view addSubview:label];

    return view; }

  • (void)collectionView:(UICollectionView )collectionView didSelectItemAtIndexPath:(NSIndexPath )indexPath { NSLog(@"你选择了");

// [self.myArray removeObjectAtIndex:indexPath.row]; //
// [collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]]; }

  • (BOOL)collectionView:(LSCollectionViewHelper )collectionView canMoveItemAtIndexPath:(NSIndexPath )indexPath { NSLog(@"canMoveItemAtIndexPath"); return YES; }

  • (void)collectionView:(LSCollectionViewHelper )collectionView moveItemAtIndexPath:(NSIndexPath )fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { NSLog(@"moveItemAtIndexPath");

    NSMutableArray *data = [self getLetterArray];

    NSNumber *index = [data objectAtIndex:fromIndexPath.item]; [data removeObjectAtIndex:fromIndexPath.item]; [data insertObject:index atIndex:toIndexPath.item]; }

  • (NSMutableArray )getLetterArray { AppDelegate appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];

    return appDelegate.letterArray; }

@end

import

@interface MyCollectionReusableView : UICollectionReusableView

@end

import "MyCollectionReusableView.h"

@implementation MyCollectionReusableView

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

    if (self) { self.backgroundColor = [UIColor orangeColor];

    UILabel *label = [[UILabel alloc] init];
    label.text = @"Decoration View";
    label.font = [UIFont systemFontOfSize:18];
    [label sizeToFit];
    label.center = CGPointMake(frame.size.width/2, frame.size.height/2);
    [self addSubview:label];

    }

    return self; }

@end

import

@interface CircleLayout : UICollectionViewLayout

@end

import "AppDelegate.h"

import "CircleLayout.h"

import "CollectionViewDataSource.h"

import "MyCollectionReusableView.h"

@interface CircleLayout() { CGSize cvSize; CGPoint cvCenter; CGFloat radius; NSInteger cellCount; }

@property (strong, nonatomic) NSMutableArray *indexPathsToAnimate;

@end

@implementation CircleLayout

  • (void)prepareLayout { [super prepareLayout];

    [self registerClass:[MyCollectionReusableView class] forDecorationViewOfKind:@"MyDecoration"];

    cvSize = self.collectionView.frame.size; cellCount = [self.collectionView numberOfItemsInSection:0]; cvCenter = CGPointMake(cvSize.width / 2.0, cvSize.height / 2.0); radius = MIN(cvSize.width, cvSize.height) / 2.5; }

  • (CGSize)collectionViewContentSize { return self.collectionView.bounds.size; }

  • (NSArray )layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray array = [NSMutableArray array];

    //add cells for (int i=0; i

@property (readonly, nonatomic) LSCollectionViewLayoutHelper *layoutHelper;

@end

import "DraggableCircleLayout.h"

import "LSCollectionViewLayoutHelper.h"

@interface DraggableCircleLayout() { LSCollectionViewLayoutHelper *_layoutHelper; } @end

@implementation DraggableCircleLayout

  • (LSCollectionViewLayoutHelper *)layoutHelper { if(_layoutHelper == nil) { _layoutHelper = [[LSCollectionViewLayoutHelper alloc] initWithCollectionViewLayout:self]; } return _layoutHelper; }

  • (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect { return [self.layoutHelper modifiedLayoutAttributesForElements:[super layoutAttributesForElementsInRect:rect]]; }

@end

收藏
1
sina weixin mail 回到顶部