UICollectionView 自定义布局+拖拽

//
//  CircleLayout.m
//  UICollectionViewTest
//
//  Created by wjr on 2019/3/4.
//  Copyright © 2019 wjr. All rights reserved.
//

#import "CircleLayout.h"
@interface CircleLayout()
@property(nonatomic,strong) NSMutableArray* attrsAry;
@property (nonatomic, strong) NSMutableArray *deleteIndexPaths;
@property (nonatomic, strong) NSMutableArray *insertIndexPaths;
@end
@implementation CircleLayout

-(void)prepareLayout
{
    [super prepareLayout];
    if (self.attrsAry == nil)
        self.attrsAry = [[NSMutableArray alloc] init];
    [self.attrsAry removeAllObjects];
    
    
    NSInteger count = [self.collectionView numberOfItemsInSection:0];
    for (int i = 0; i < count; i++)
    {
        NSIndexPath* indexPath = [NSIndexPath indexPathForItem:i inSection:0];
        UICollectionViewLayoutAttributes* attr  = [self layoutAttributesForItemAtIndexPath:indexPath];
        [self.attrsAry addObject:attr];
    }
}

- (nullable NSArray<__kindof UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    //NSLog(@"1");
    return self.attrsAry;
}

- (nullable UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger count = [self.collectionView numberOfItemsInSection:0];
    CGFloat radius = 180;
    CGFloat ox = self.collectionView.frame.size.width * 0.5;
    CGFloat oy = self.collectionView.frame.size.height * 0.5;
    CGFloat angle = 2 * M_PI * indexPath.item / count;
    CGFloat  centerX = ox + radius*cos(angle);
    CGFloat  centerY = oy  + radius*sin(angle);    
    UICollectionViewLayoutAttributes* attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    attrs.center = CGPointMake(centerX, centerY);
    attrs.size = CGSizeMake(50, 50);
    return attrs;
}

- (NSIndexPath *)targetIndexPathForInteractivelyMovingItem:(NSIndexPath *)previousIndexPath withPosition:(CGPoint)position
{
    //NSLog(@"target row = %ld,section=%ld",previousIndexPath.row,previousIndexPath.section);
    return [self.collectionView indexPathForItemAtPoint:position];
    return [self getPath:position];
    return [NSIndexPath indexPathForRow:9 inSection:0];
}

-(NSIndexPath*)getPath:(CGPoint)position
{
    for (int i = 0; i < self.attrsAry.count; i++)
    {
        
        UICollectionViewLayoutAttributes* attr  = [self.attrsAry objectAtIndex:i];
        if (CGRectContainsPoint(attr.frame,position))
        {
            return attr.indexPath;
        }
    }
    return nil;
}



-(CGSize)collectionViewContentSize
{
    return CGSizeMake(500, 500);
}

- (void)prepareForCollectionViewUpdates:(NSArray *)updateItems
{
    // Keep track of insert and delete index paths
    [super prepareForCollectionViewUpdates:updateItems];
    
    self.deleteIndexPaths = [NSMutableArray array];
    self.insertIndexPaths = [NSMutableArray array];
    
    for (UICollectionViewUpdateItem *update in updateItems)
    {
        if (update.updateAction == UICollectionUpdateActionDelete)
        {
            [self.deleteIndexPaths addObject:update.indexPathBeforeUpdate];
        }
        else if (update.updateAction == UICollectionUpdateActionInsert)
        {
            [self.insertIndexPaths addObject:update.indexPathAfterUpdate];
        }
    }
}

- (void)finalizeCollectionViewUpdates
{
    [super finalizeCollectionViewUpdates];
    // release the insert and delete index paths
    self.deleteIndexPaths = nil;
    self.insertIndexPaths = nil;
}

- (UICollectionViewLayoutAttributes *)initialLayoutAttributesForAppearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    // Must call super
    UICollectionViewLayoutAttributes *attributes = [super initialLayoutAttributesForAppearingItemAtIndexPath:itemIndexPath];
    
    if ([self.insertIndexPaths containsObject:itemIndexPath])
    {
        // only change attributes on inserted cells
        if (!attributes)
            attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
        
        // Configure attributes ...
        attributes.alpha = 0.0;
        CGFloat ox = self.collectionView.frame.size.width * 0.5;
        CGFloat oy = self.collectionView.frame.size.height * 0.5;
        attributes.center = CGPointMake(ox, oy);
    }
    
    return attributes;
}

// Note: name of method changed
// Also this gets called for all visible cells (not just the deleted ones) and
// even gets called when inserting cells!
- (UICollectionViewLayoutAttributes *)finalLayoutAttributesForDisappearingItemAtIndexPath:(NSIndexPath *)itemIndexPath
{
    // So far, calling super hasn't been strictly necessary here, but leaving it in
    // for good measure
    UICollectionViewLayoutAttributes *attributes = [super finalLayoutAttributesForDisappearingItemAtIndexPath:itemIndexPath];
    
    if ([self.deleteIndexPaths containsObject:itemIndexPath])
    {
        // only change attributes on deleted cells
        if (!attributes)
            attributes = [self layoutAttributesForItemAtIndexPath:itemIndexPath];
        
        // Configure attributes ...
        attributes.alpha = 0.0;
        CGFloat ox = self.collectionView.frame.size.width * 0.5;
        CGFloat oy = self.collectionView.frame.size.height * 0.5;
        attributes.center = CGPointMake(ox, oy);
    }
    
    return attributes;
}

@end

 ViewController

//
//  ViewController.m
//  UICollectionViewTest
//
//  Created by wjr on 16/6/2.
//  Copyright © 2016年 wjr. All rights reserved.
//

#import "ViewController.h"
#import "CircleLayout.h"
@interface ViewController ()
@property(nonatomic,strong) NSMutableArray* imageAry;
@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    CircleLayout* layout = [[CircleLayout alloc] init];
    //UICollectionViewFlowLayout* layouts = [[UICollectionViewFlowLayout alloc] init];
    //layouts.scrollDirection = UICollectionViewScrollDirectionVertical;
    
    CGSize size = self.view.bounds.size;
    self.collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 44 + 50, size.width, size.height - 44 - 50) collectionViewLayout:layout];
    self.collectionView.backgroundColor = [UIColor orangeColor];
    self.collectionView.delegate = self;
    self.collectionView.dataSource = self;
    [self.collectionView registerClass:[MyCollectionViewCell class] forCellWithReuseIdentifier:@"cell"];
    [self.view addSubview:self.collectionView];
    
    UILongPressGestureRecognizer *longpress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPress:)];
    longpress.minimumPressDuration = 0.5;
    [self.collectionView addGestureRecognizer:longpress];
  
    self.imageAry = [[NSMutableArray alloc] init];
    
    int index = 1;
    for (int i = 0; i < 10; i++)
    {
        NSDictionary* dic = @{@"image":[NSString stringWithFormat:@"%d.png",index],@"text":[NSString stringWithFormat:@"%d",i]};
        [self.imageAry addObject:dic];
        index++;
        if (index > 11) {
            index=1;
        }
    }
    
    
    UIButton* button = [UIButton new];
    [button setFrame:CGRectMake(0, 44, 100, 50)];
    [button setTitle:@"添加" forState:UIControlStateNormal];
    button.backgroundColor = [UIColor redColor];
    [button addTarget:self action:@selector(add) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
    button = [UIButton new];
    [button setFrame:CGRectMake(110, 44, 100, 50)];
    [button setTitle:@"删除" forState:UIControlStateNormal];
    button.backgroundColor = [UIColor redColor];
    [button addTarget:self action:@selector(remove) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
    
}

-(void)add
{
    int index = (int)self.imageAry.count;
    NSDictionary* dic = @{@"image":[NSString stringWithFormat:@"%d.png",1],@"text":[NSString stringWithFormat:@"%d",index]};
    [self.imageAry insertObject:dic atIndex:0];
    [self.collectionView performBatchUpdates:^{
        [self.collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:0 inSection:0]]];
    } completion:nil];
}

-(void)remove
{
    int index = (int)self.imageAry.count - 1;
    [self.imageAry removeObjectAtIndex:index];
    [self.collectionView performBatchUpdates:^{
        [self.collectionView deleteItemsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForItem:index inSection:0]]];
        
    } completion:nil];
}

-(void)longPress:(UILongPressGestureRecognizer*)recognizer
{
    switch (recognizer.state) {
        case UIGestureRecognizerStateBegan: {
            [self handleEditingMoveWhenGestureBegan:recognizer];
            break;
        }
        case UIGestureRecognizerStateChanged: {
            [self handleEditingMoveWhenGestureChanged:recognizer];
            break;
        }
        case UIGestureRecognizerStateEnded: {
            [self handleEditingMoveWhenGestureEnded:recognizer];
            break;
        }
        default: {
            [self handleEditingMoveWhenGestureCanceledOrFailed:recognizer];
            break;
        }
    }
}
- (void)handleEditingMoveWhenGestureBegan:(UILongPressGestureRecognizer *)recognizer{
    
    CGPoint pressPoint = [recognizer locationInView:self.collectionView];
    NSIndexPath* selectIndexPath = [self.collectionView indexPathForItemAtPoint:pressPoint];
    //MyCollectionViewCell *cell = (MyCollectionViewCell *)[self.collectionView cellForItemAtIndexPath:selectIndexPath];
    [self.collectionView beginInteractiveMovementForItemAtIndexPath:selectIndexPath];
    
}
- (void)handleEditingMoveWhenGestureChanged:(UILongPressGestureRecognizer *)recognizer{
    
    CGPoint pressPoint = [recognizer locationInView:self.collectionView];
    [self.collectionView updateInteractiveMovementTargetPosition:pressPoint];
    
}
- (void)handleEditingMoveWhenGestureEnded:(UILongPressGestureRecognizer *)recognizer{
    
    [self.collectionView endInteractiveMovement];
    
}
- (void)handleEditingMoveWhenGestureCanceledOrFailed:(UILongPressGestureRecognizer *)recognizer{
    
    CGPoint pressPoint = [recognizer locationInView:self.collectionView];
    [self.collectionView cancelInteractiveMovement];
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return self.imageAry.count;
}



// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger row = [indexPath row];
    NSInteger section = [indexPath section];
    
    MyCollectionViewCell* cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];
    NSDictionary* dic = [self.imageAry objectAtIndex:row];
    cell.imageView.image = [UIImage imageNamed:[dic objectForKey:@"image"]];
    cell.textView.text = [dic objectForKey:@"text"];
    return cell;
}



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

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger row = [indexPath row];
    return CGSizeMake(50, 50);
}
-(UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    return UIEdgeInsetsMake(20, 20, 20, 20);
}

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger row = [indexPath row];
    NSInteger section = [indexPath section];
    [self.collectionView deselectItemAtIndexPath:indexPath animated:NO];
    NSLog(@"选中了 %ld,%ld",section,row);
}
- (void)collectionView:(UICollectionView *)collectionView didHighlightItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
    cell.backgroundColor = [UIColor greenColor];
}
- (void)collectionView:(UICollectionView *)collectionView didUnhighlightItemAtIndexPath:(nonnull NSIndexPath *)indexPath
{
    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
    cell.backgroundColor = [UIColor blueColor];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section
{
    int screenWidth = [[UIScreen mainScreen] bounds].size.width;
    return (CGSize){screenWidth,44};
}

//- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
//{
//    
//    if([kind isEqualToString:UICollectionElementKindSectionHeader])
//    {
//        MyCollectionReusableView *headerView = [collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:@"header" forIndexPath:indexPath];
//        if(headerView == nil)
//        {
//            headerView = [[MyCollectionReusableView alloc] init];
//        }
//        headerView.backgroundColor = [UIColor grayColor];
//        
//        return headerView;
//    }
//    else if([kind isEqualToString:UICollectionElementKindSectionFooter])
//    {
//        
//    }
//    
//    return nil;
//}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section
{
    return 50;
}

 copy and paste 的实现
//- (void)collectionView:(UICollectionView *)collectionView performAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender
//{
//    if([NSStringFromSelector(action) isEqualToString:@"copy:"])
//    {
//        //        NSLog(@"-------------执行拷贝-------------");
//        [collectionView performBatchUpdates:^{
//            NSLog(@"33");
//        } completion:nil];
//    }
//    else if([NSStringFromSelector(action) isEqualToString:@"paste:"])
//    {
//        NSLog(@"-------------执行粘贴-------------");
//    }
//}
//- (BOOL)collectionView:(UICollectionView *)collectionView shouldShowMenuForItemAtIndexPath:(NSIndexPath *)indexPath
//{
//    return TRUE;
//}
//- (BOOL)collectionView:(UICollectionView *)collectionView canPerformAction:(SEL)action forItemAtIndexPath:(NSIndexPath *)indexPath withSender:(nullable id)sender
//{
//    if([NSStringFromSelector(action) isEqualToString:@"copy:"])
//    {
//        return YES;
//    }
//    else if([NSStringFromSelector(action) isEqualToString:@"paste:"])
//    {
//        return YES;
//    }
//    return NO;
//}

- (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}
- (void)collectionView:(UICollectionView *)collectionView moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath*)destinationIndexPath
{
    if (sourceIndexPath.item > destinationIndexPath.item )
    {
        NSString* text = [self.imageAry objectAtIndex:sourceIndexPath.item];
        [self.imageAry removeObjectAtIndex:sourceIndexPath.item];
        [self.imageAry insertObject:text atIndex:destinationIndexPath.item];
    }
    else
    {
        [self.imageAry exchangeObjectAtIndex:sourceIndexPath.item withObjectAtIndex:destinationIndexPath.item];
    }
    NSLog(@"%@",self.imageAry);
}



@end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值