在iOS中移动UICollectionView的单元格?

在iOS中移动UICollectionView的单元格?,第1张

概述我有一个UICollectionView.I我试图给它作为 SpringBoard的功能.我有能力给每个单元格摇动动画.但是我想当图标摇动时,我应该能够移动他们. 为了摇动单元格,我已经在每个单元格上添加了UILongPressGesture.当手势结束时,我已经添加了一个自定义动画.还在左上角添加了一个删除按钮. 长按手势代码: declaration of variablesCGPoint 我有一个UICollectionVIEw.I我试图给它作为 SpringBoard的功能.我有能力给每个单元格摇动动画.但是我想当图标摇动时,我应该能够移动他们.

为了摇动单元格,我已经在每个单元格上添加了UILongPressGesture.当手势结束时,我已经添加了一个自定义动画.还在左上角添加了一个删除按钮.

长按手势代码:

declaration of variablesCGPoint p;UILongPressGestureRecognizer *lpgr;NSIndexPath *gesture_indexPath;

添加手势到集合视图

lpgr    = [[UILongPressGestureRecognizer alloc]       initWithTarget:self action:@selector(handleLongPress:)];        lpgr.minimumPressDuration = .3; // To detect after how many seconds you want shake the cells        lpgr.delegate = self;        [self.collection_vIEw addGestureRecognizer:lpgr];    lpgr.delaystouchesBegan = YES;

回调方法

-(voID)handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer{    if (gestureRecognizer.state != UIGestureRecognizerStateEnded)    {        return;    }    p = [gestureRecognizer locationInVIEw:self.collection_vIEw];    NSIndexPath *indexPath = [self.collection_vIEw indexPathForItemAtPoint:p];    if (indexPath == nil)    {        NSLog(@"Couldn't find index path");    }    else    {        [[NSUserDefaults standardUserDefaults]setValue:@"yes" forKey:@"longpressed"];        [self.collection_vIEw reloadData];    }}

单元格在inde路径项

- (UICollectionVIEwCell *)collectionVIEw:(UICollectionVIEw *)collectionVIEw cellForItemAtIndexPath:(NSIndexPath *)indexPath{    NSLog(@"arr_album index row");    BlogalbumCell  *cell;    static Nsstring *IDentifIEr = @"UserBlogalbum";    cell = [collectionVIEw dequeueReusableCellWithReuseIDentifIEr:IDentifIEr forIndexPath:indexPath];    UserAlbum *user_allbum=[arr_userAlbums objectAtIndex:indexPath.row];    cell.label_blog_name.text=user_allbum.album_name;    cell.image_blog_image.image = [UIImage imagenamed:@"more.png"];    [cell.image_blog_image setimageWithURL:[NSURL URLWithString:[IMAGE_BASE_URL stringByAppendingString:user_allbum.album_image]]];    if([[[NSUserDefaults standardUserDefaults]valueForKey:@"longpressed"] isEqualToString:@"yes"])    {        CABasicAnimation* anim = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];        [anim setTovalue:[NSNumber numberWithfloat:0.0f]];        [anim setFromValue:[NSNumber numberWithDouble:M_PI/50]];        [anim setDuration:0.1];        [anim setRepeatCount:NSUIntegerMax];        [anim setautoreverses:YES];        cell.layer.shouldRasterize = YES;        [cell.layer addAnimation:anim forKey:@"SpringboardShake"];        CGfloat delbuttonSize = 20;        UIbutton *delbutton = [[UIbutton alloc] initWithFrame:CGRectMake(0,delbuttonSize,delbuttonSize)];        delbutton.center = CGPointMake(9,10);        delbutton.backgroundcolor = [UIcolor clearcolor];        [delbutton setimage: [UIImage imagenamed:@"cross_30.png"] forState:UIControlStatenormal];        [cell addSubvIEw:delbutton];        [delbutton addTarget:self action:@selector(deleteRecipe:) forControlEvents:UIControlEventtouchUpInsIDe];    }    else if ([[[NSUserDefaults standardUserDefaults]valueForKey:@"singleTap"] isEqualToString:@"yes"])    {         for(UIVIEw *subvIEw in [cell subvIEws])        {            if([subvIEw isKindOfClass:[UIbutton class]])            {                [subvIEw removeFromSupervIEw];            }            else            {                // Do nothing - not a UIbutton or subclass instance            }        }        [cell.layer removeAllAnimations];        // _deletebutton.hIDden = YES;         // [_deletebutton removeFromSupervIEw];    }        return cell;}

在这里工作正常

为了移动单元格,我做了一个示例应用程序,其中我添加了UICollectionVIEwController&覆盖此方法

-(voID)collectionVIEw:(UICollectionVIEw *)collectionVIEw moveItemAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{    NSLog(@"Move at index path called");}

这也很好.它也使用长按手势&当手势被取消时,我可以移动细胞.但现在问题是在一个我可以移动单元格或动画他们.如果我添加我的自定义手势,那么我无法移动图像.请告诉我如何删除这个问题?

解决方法 看看这个名为 DragDropCollectionView的项目,它实现拖放以及动画.

编辑:这个问题可以分解成2个较小的子问题:

>如何动画细胞
>如何使用拖放重新排序单元格.

您应该将这两个解决方案组合到UICollectionVIEw的子文件夹中,以获得您的主要解决方案.

如何动画细胞

要获得摆动动画,您需要添加2种不同的动画效果:

>垂直移动单元格,上下移动
>旋转单元格
>最后,为每个单元格添加一个随机的间隔时间,所以看起来单元格不能均匀地动画化

这是代码:

@interface DragDropCollectionVIEw ()@property (assign,nonatomic) BOol isWiggling;@end@implementation DragDropCollectionVIEw//Start and Stop methods for wiggle- (voID) startWiggle {    for (UICollectionVIEwCell *cell in self.visibleCells) {        [self adDWiggleAnimationToCell:cell];    }    self.isWiggling = true;}- (voID)stopWiggle {    for (UICollectionVIEwCell *cell in self.visibleCells) {        [cell.layer removeAllAnimations];    }    self.isWiggling = false;}//- (UICollectionVIEwCell *)dequ- (UICollectionVIEwCell *)dequeueReusableCellWithReuseIDentifIEr:(Nsstring *)IDentifIEr forIndexPath:(nonnull NSIndexPath *)indexPath{    UICollectionVIEwCell *cell = [super dequeueReusableCellWithReuseIDentifIEr:IDentifIEr forIndexPath:indexPath];    if (self.isWiggling) {        [self adDWiggleAnimationToCell:cell];    } else {        [cell.layer removeAllAnimations];    }    return [[UICollectionVIEwCell alloc] init];}//Animations- (voID)adDWiggleAnimationToCell:(UICollectionVIEwCell *)cell {    [CATransaction begin];    [CATransaction setdisableActions:false];    [cell.layer addAnimation:[self rotationAnimation] forKey:@"rotation"];    [cell.layer addAnimation:[self bounceAnimation] forKey:@"bounce"];    [CATransaction commit];}- (CAKeyframeAnimation *)rotationAnimation {    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];    CGfloat angle = 0.04;    NSTimeInterval duration = 0.1;    double variance = 0.025;    animation.values = @[@(angle),@(-1 * angle)];    animation.autoreverses = YES;    animation.duration = [self randomizeInterval:duration withVariance: variance];    animation.repeatCount = INFINITY;    return animation;}- (CAKeyframeAnimation *)bounceAnimation {    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.y"];    CGfloat bounce = 3.0;    NSTimeInterval duration = 0.12;    double variance = 0.025;    animation.values = @[@(bounce),@(-1 * bounce)];    animation.autoreverses = YES;    animation.duration = [self randomizeInterval:duration withVariance: variance];    animation.repeatCount = INFINITY;    return animation;}- (NSTimeInterval)randomizeInterval:(NSTimeInterval)interval withVariance:(double)variance {    double randomDecimal = (arc4random() % 1000 - 500.0) / 500.0;    return interval + variance * randomDecimal;}

如何使用拖放重新排序单元格

所以想法是这样的:你不是移动实际的单元格,而是移动一个UIImageVIEw与单元格内容的UIImage.

算法或多或少是这样的.我把它分解成3个部分,手势识别器,改变和结束

gestureRecognizerBegan:

>当手势识别器开始时,确定长按确实在一个单元格上(而不是在空白的空间)
>获取单元格的UIImage(请参阅我的方法“getRasterizedImageOfCell”)
>隐藏单元格(即Alpha = 0),创建具有单元格确切框架的UIImageVIEw,以便用户不会意识到您实际上已隐藏单元格,并且实际上正在使用imagevIEw.

gestureRecognizerChanged:

>更新UIImageVIEw的中心,使其随手指移动.
>如果用户已经停止移动他的眼睛,即他将鼠标悬停在要替换的单元格上,那么现在需要交换单元格. (看看我的函数“shouldSwapCells”,这个方法返回一个bool是否单元格应该交换)
>将要拖动的单元格移动到新的indexPath. (看我的方法“swapDraggedCell”). UICollectionVIEw有一个称为“moveItemAtIndexPath:toIndexPath”的内置方法,我不知道UItableVIEw是否具有相同的东西

gestureRecognizerEnd:

>将UIImageVIEw“放下”回到单元格
>将单元格Alpha从0.0更改为1.0,并从视图中删除UIImageVIEw.

这是代码:

@interface DragDropCollectionVIEw ()@property (strong,nonatomic) NSIndexPath *draggedCellindexPath;@property (strong,nonatomic) UIImageVIEw *draggingImageVIEw;@property (assign,nonatomic) CGPoint touchOffsetFromCenterOfCell;@property (strong,nonatomic) UILongPressGestureRecognizer *longPressRecognizer;@end@implementation DragDropCollectionVIEw- (voID)handleLongPress:(UILongPressGestureRecognizer *)longPressRecognizer {    CGPoint touchLocation = [longPressRecognizer locationInVIEw:self];    switch (longPressRecognizer.state) {        case UIGestureRecognizerStateBegan: {            self.draggedCellindexPath = [self indexPathForItemAtPoint:touchLocation];            if (self.draggedCellindexPath != nil) {                UICollectionVIEwCell *draggedCell = [self cellForItemAtIndexPath:self.draggedCellindexPath];                self.draggingImageVIEw = [[UIImageVIEw alloc] initWithImage:[self rasterizedImagecopyOfCell:draggedCell]];                self.draggingImageVIEw.center = draggedCell.center;                [self addSubvIEw:self.draggingImageVIEw];                draggedCell.Alpha = 0.0;                self.touchOffsetFromCenterOfCell = CGPointMake(draggedCell.center.x - touchLocation.x,draggedCell.center.y - touchLocation.y);                [UIVIEw animateWithDuration:0.4 animations:^{                    self.draggingImageVIEw.transform = CGAffinetransformMakeScale(1.3,1.3);                    self.draggingImageVIEw.Alpha = 0.8;                }];            }            break;        }        case UIGestureRecognizerStateChanged: {            if (self.draggedCellindexPath != nil) {                self.draggingImageVIEw.center = CGPointMake(touchLocation.x + self.touchOffsetFromCenterOfCell.x,touchLocation.y + self.touchOffsetFromCenterOfCell.y);            }            float PingInterval = 0.3;            dispatch_after(dispatch_time(disPATCH_TIME_Now,(int64_t)(PingInterval * NSEC_PER_SEC)),dispatch_get_main_queue(),^{                NSIndexPath *newIndexPath = [self indexPathToSwapCellWithAtPrevIoUstouchLocation:touchLocation];                if (newIndexPath) {                    [self swapDraggedCellWithCellAtIndexPath:newIndexPath];                }            });            break;        }        case UIGestureRecognizerStateEnded: {            if (self.draggedCellindexPath != nil ) {                UICollectionVIEwCell *draggedCell = [self cellForItemAtIndexPath:self.draggedCellindexPath];                [UIVIEw animateWithDuration:0.4 animations:^{                    self.draggingImageVIEw.transform = CGAffinetransformIDentity;                    self.draggingImageVIEw.Alpha = 1.0;                    if (draggedCell != nil) {                        self.draggingImageVIEw.center = draggedCell.center;                    }                } completion:^(BOol finished) {                    [self.draggingImageVIEw removeFromSupervIEw];                    self.draggingImageVIEw = nil;                    if (draggedCell != nil) {                        draggedCell.Alpha = 1.0;                        self.draggedCellindexPath = nil;                    }                }];            }        }        default:            break;    }}- (UIImage *)rasterizedImagecopyOfCell:(UICollectionVIEwCell *)cell {    UIGraphicsBeginImageContextWithOptions(cell.bounds.size,false,0.0);    [cell.layer renderInContext:UIGraphicsGetCurrentContext()];    UIImage *image = UIGraphicsGetimageFromCurrentimageContext();    return image;}- (NSIndexPath *)indexPathToSwapCellWithAtPrevIoUstouchLocation:(CGPoint)prevIoUstouchLocation {    CGPoint currenttouchLocation = [self.longPressRecognizer locationInVIEw:self];    if (!isnan(currenttouchLocation.x) && !isnan(currenttouchLocation.y)) {        if ([self distanceBetweenPoints:currenttouchLocation secondPoint:prevIoUstouchLocation] < 20.0) {            NSIndexPath *newIndexPath = [self indexPathForItemAtPoint:currenttouchLocation];            return newIndexPath;        }    }    return nil;}- (CGfloat)distanceBetweenPoints:(CGPoint)firstPoint secondPoint:(CGPoint)secondPoint {    CGfloat xdistance = firstPoint.x - secondPoint.x;    CGfloat ydistance = firstPoint.y - secondPoint.y;    return sqrtf(xdistance * xdistance + ydistance * ydistance);}- (voID)swapDraggedCellWithCellAtIndexPath:(NSIndexPath *)newIndexPath {    [self moveItemAtIndexPath:self.draggedCellindexPath toIndexPath:newIndexPath];    UICollectionVIEwCell *draggedCell = [self cellForItemAtIndexPath:newIndexPath];    draggedCell.Alpha = 0.0;    self.draggedCellindexPath = newIndexPath;}

希望这可以帮助 :)

总结

以上是内存溢出为你收集整理的在iOS中移动UICollectionView的单元格?全部内容,希望文章能够帮你解决在iOS中移动UICollectionView的单元格?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1098181.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存