使用UICollectionView创建一堆照片,用户可以轻扫

时间:2014-03-19 18:16:56

标签: ios iphone objective-c uicollectionview uicollectionviewlayout

我正在尝试使用UICollectionView创建一堆照片,用户可以将照片滑到一边。当拖动照片时,它会变小(达到最小比例)并且后面的照片会放大到最大比例。此最大比例是前景照片的原始大小。

当拖动前景照片的平移手势结束时,如果是最小刻度,则将其发送到堆栈的背面,否则,将其动画回屏幕中心并放大回原始大小(以及背后不断增长的照片)。

我希望你还和我在一起哈哈。

现在,假设被拖动的照片处于最小尺寸,我删除了UICollectionView的用户互动,再次将照片动画显示到屏幕中心,并将其大小设置为动画以匹配其余部分背景图片。然后我将单元格发送到UICollectionView子视图的后面。

一旦完成所有这些动画,我会通过在前面添加照片来更新我的数据源(图像数组),然后在前面删除该照片。

然后,我更新UICollectionView。这包括批量更新,其中我在NSIndexPath 0:0删除项目,然后在NSIndexPath插入项目([照片计数] - 1):0。

当此批量更新完成后,我重新加载UICollectionView(因为只有NSIndexPath 0:0处的项目具有平移手势)并重新添加用户交互到UICollectionView

我希望这是有道理的。

备注

背景照片的大小是80%的百分比。

前景照片的大小是100%的百分比。

这是相对于适合iPhone屏幕的UICollectionView

我的问题

我的代码似乎运行得很好。我的问题来自于当我将手指从屏幕上移开(平移手势结束)和照片的动画(将其居中到屏幕中心并像其他背景照片一样调整大小)结束。

拖出的照片重新出现在屏幕上,尺寸从背景照片的尺寸(80%)到前景照片的尺寸(100%)然后逐渐消失。一旦发生这种情况,照片将按预期重新排序。

有谁知道为什么会这样?

这是我的Pan Gesture代码:

CGPoint touchTranslation = [gesture translationInView:self.view];

static CGPoint originalCenter;

DIGalleryCollectionViewLayout *galleryCollectionViewLayout = (DIGalleryCollectionViewLayout *)self.galleryCollectionView.collectionViewLayout;

if (gesture.state == UIGestureRecognizerStateBegan) {
    //
    //  Began.
    //
    originalCenter = gesture.view.center;
} else if (gesture.state == UIGestureRecognizerStateChanged) {
    //
    //  Changed.
    //
    CGPoint translate = [gesture translationInView:gesture.view.superview];

    touchTranslation = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y);
    [gesture.view setCenter:touchTranslation];

    CGPoint pointsPhotoIsMovedBy = CGPointMake(fabsf(fabsf(originalCenter.x) - fabsf(touchTranslation.x)),
                                               fabsf(fabsf(originalCenter.y) - fabsf(touchTranslation.y)));

    //  Update cells.
    //
    CGFloat currentIncrement = MAX(pointsPhotoIsMovedBy.x, pointsPhotoIsMovedBy.y);

    for (NSIndexPath *indexPath in self.galleryCollectionView.indexPathsForVisibleItems) {
        UICollectionViewCell *cell = [self.galleryCollectionView cellForItemAtIndexPath:indexPath];

        if ([indexPath isEqual:[NSIndexPath indexPathForItem:0 inSection:0]]) {
            //
            //      Front.
            //
            CGFloat frontScalePercent = MIN(GalleryCollectionViewLayoutFrontRatioDefault,
                                            MAX(GalleryViewFrontScaleMinimum, GalleryCollectionViewLayoutFrontRatioDefault - (currentIncrement / 250.0f)));

            [cell setTransform:CGAffineTransformMakeScale(frontScalePercent, frontScalePercent)];
        } else if ([indexPath isEqual:[NSIndexPath indexPathForItem:1 inSection:0]]) {
            //
            //      Next.
            //
            CGFloat nextScalePercent = MAX(GalleryCollectionViewLayoutBackRatioDefault,
                                           MIN(GalleryViewNextScaleMaximum, (currentIncrement / 150.0f)));

            [cell setTransform:CGAffineTransformMakeScale(nextScalePercent, nextScalePercent)];
        } else {
            //
            //      Background.
            //
            [cell setTransform:CGAffineTransformMakeScale(GalleryCollectionViewLayoutBackRatioDefault,
                                                          GalleryCollectionViewLayoutBackRatioDefault)];
        }
    }
} else if (gesture.state == UIGestureRecognizerStateEnded) {
    //
    //  Ended.
    //
    if (gesture.view.transform.a == GalleryViewFrontScaleMinimum) {
        //
        //  Next photo.
        //
        [self.galleryCollectionView setUserInteractionEnabled:NO];
        [self.galleryCollectionView sendSubviewToBack:gesture.view];

        [UIView animateWithDuration:0.3f
                         animations:^{
                             [gesture.view setCenter:self.galleryCollectionView.center];
                             [gesture.view setTransform:CGAffineTransformMakeScale(GalleryCollectionViewLayoutBackRatioDefault,
                                                                                   GalleryCollectionViewLayoutBackRatioDefault)];
                         }
                         completion:^(BOOL finished) {
                             //
                             //          Data source
                             //
                             NSMutableArray *photos = [self.photos mutableCopy];

                             [photos addObject:[photos objectAtIndex:0]];
                             [photos removeObjectAtIndex:0];

                             [self setPhotos:photos];

                             //          Contents
                             //
                             [self.galleryCollectionView performBatchUpdates:^{
                                 [self.galleryCollectionView deleteItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:0 inSection:0]]];
                                 [self.galleryCollectionView insertItemsAtIndexPaths:@[[NSIndexPath indexPathForItem:(self.photos.count - 1) inSection:0]]];
                             } completion:^(BOOL finished) {
                                 [self.galleryCollectionView reloadData];

                                 [self.galleryCollectionView setUserInteractionEnabled:YES];
                             }];
                         }];
    } else {
        //
        //  Stay.
        //
        [UIView animateWithDuration:0.3f
                              delay:0.0f
                            options:UIViewAnimationOptionCurveEaseIn
                         animations:^{
                             //
                             // Front cell.
                             //
                             [gesture.view setCenter:self.galleryCollectionView.center];
                             [gesture.view setTransform:CGAffineTransformMakeScale(GalleryCollectionViewLayoutFrontRatioDefault,
                                                                                   GalleryCollectionViewLayoutFrontRatioDefault)];

                             // Next cell.
                             //
                             for (NSIndexPath *indexPath in self.galleryCollectionView.indexPathsForVisibleItems) {
                                 if ([indexPath isEqual:[NSIndexPath indexPathForItem:1 inSection:0]]) {
                                     //
                                     //      Next.
                                     //
                                     UICollectionViewCell *cell = [self.galleryCollectionView cellForItemAtIndexPath:indexPath];
                                     [cell setTransform:CGAffineTransformMakeScale(GalleryCollectionViewLayoutBackRatioDefault,
                                                                                   GalleryCollectionViewLayoutBackRatioDefault)];
                                 }
                             }
                         }
                         completion:^(BOOL finished) {
                             [galleryCollectionViewLayout setFrontRatio:GalleryCollectionViewLayoutFrontRatioDefault];
                             [galleryCollectionViewLayout setNextRatio:GalleryCollectionViewLayoutBackRatioDefault];
                             [galleryCollectionViewLayout invalidateLayout];
                         }];
    }
}

这是我的prepareLayout:集合视图布局的代码:

NSMutableDictionary *newLayoutInfo = [NSMutableDictionary dictionary];
NSMutableDictionary *cellLayoutInfo = [NSMutableDictionary dictionary];

NSIndexPath *indexPath;

for (NSInteger section = 0; section < [self.collectionView numberOfSections]; section++) {
    NSInteger itemCount = [self.collectionView numberOfItemsInSection:section];

    for (NSInteger item = 0; item < itemCount; item++) {
        indexPath = [NSIndexPath indexPathForItem:item inSection:section];

        UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];

        [itemAttributes setSize:[self sizeForPhotoAtIndexPath:indexPath inContainerOfSize:self.collectionView.bounds.size]];
        [itemAttributes setCenter:self.collectionView.center];

        //  Z Index.
        //
        NSInteger zIndex = itemCount - item;
        [itemAttributes setZIndex:zIndex];

        //  Scale cells based on z position.
        //
        if (zIndex == itemCount) {
            //
            //      Foreground.
            //
            [itemAttributes setTransform:CGAffineTransformMakeScale(self.frontRatio, self.frontRatio)];
        } else if (zIndex == itemCount - 1) {
            //
            //      Next.
            //
            [itemAttributes setTransform:CGAffineTransformMakeScale(self.nextRatio, self.nextRatio)];
        } else {
            //
            //      Background.
            //
            [itemAttributes setTransform:CGAffineTransformMakeScale(GalleryCollectionViewLayoutBackRatioDefault,
                                                                    GalleryCollectionViewLayoutBackRatioDefault)];
        }

        cellLayoutInfo[indexPath] = itemAttributes;
    }
}

newLayoutInfo[GalleryCollectionViewLayoutCellKind] = cellLayoutInfo;

self.layoutInfo = newLayoutInfo;

作为附加参考,这是我的sizeForPhotoAtIndexPath代码:inContainerOfSize:

UIImage *photo = [[(DIGalleryViewController *)self.collectionView.delegate photos] objectAtIndex:indexPath.row];

CGSize size = CGSizeMake(photo.size.width, photo.size.height);

UIGraphicsBeginImageContext(containerSize);
[photo drawInRect:CGRectMake(0.0f, 0.0f, containerSize.width, containerSize.height)];
UIImage *resizedPhoto = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

CGFloat ratio = photo.size.width / resizedPhoto.size.width;

size = CGSizeMake(resizedPhoto.size.width, photo.size.height / ratio);

return size;

0 个答案:

没有答案