【问题标题】:UICollectionView full screen zoom on UICollectionViewCellUICollectionView 在 UICollectionViewCell 上全屏缩放
【发布时间】:2014-09-04 16:02:33
【问题描述】:

如何放大UICollectionViewCell 使其全屏显示?我已经扩展了UICollectionViewFlowLayout 并且在我的视图控制器中当一个单元被点击时我正在这样做:

CGPoint pointInCollectionView = [gesture locationInView:self.collectionView];
NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:pointInCollectionView];
UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath];

NSLog(@"Selected cell %@", selectedIndexPath);

不确定从这里去哪里。 UICollectionView 是否应该负责显示放大的单元格?或者我应该创建一个新的视图控制器来全屏显示单元格的内容(图像)?

【问题讨论】:

  • 你需要去另一个viewcontroller来详细显示图像
  • 创建一个新控制器并推送/模态到那个肯定会容易得多,或者只是创建一个新视图并将其显示在当前集合视图上。修改你的单元格以扩展听起来像是一个不必要的头痛。
  • @Stonz2 我非常希望有扩展效果。 iOS 上的 Facebook 应用在相册中执行此操作。

标签: ios objective-c uicollectionview zooming fullscreen


【解决方案1】:

您可以使用适合您问题的MWPhotoBrowser。它支持带有点击缩放功能的网格。你可以从here得到它

网格

为了正确显示缩略图的网格,您必须确保属性 enableGrid 设置为 YES,并实现以下委托方法:

(id <MWPhoto>)photoBrowser:(MWPhotoBrowser *)photoBrowser thumbPhotoAtIndex:(NSUInteger)index;

通过启用 startOnGrid 属性,照片浏览器也可以在网格上启动。

【讨论】:

    【解决方案2】:

    您可以简单地使用另一种布局(类似于您已有的布局),其中项目大小较大,然后在 collectionView 上执行setCollectionViewLayout:animated:completion:

    您不需要新的视图控制器。您的数据源保持不变。您甚至可以使用相同的单元格类,只需确保它知道何时为更大的单元格内容大小进行布局,何时不布局。

    我很确定 Facebook 在 Paper 中就是这样做的,因为没有重新加载内容,即 [collectionView reloadData] 似乎从未被调用(会导致滚动偏移的闪烁和重置等)。这似乎是最直接的解决方案。

    CGPoint pointInCollectionView = [gesture locationInView:self.collectionView];
    NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:pointInCollectionView];
    UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath];
    
    NSLog(@"Selected cell %@", selectedIndexPath);
    
    __weak typeof(self) weakSelf = self;
    
    [self.collectionView setCollectionViewLayout:newLayout animated:YES completion:^{
    
        [weakSelf.collectionView scrollToItemAtIndexPath:selectedIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
    
    }];
    

    【讨论】:

    • Paper 没有这样做 - 他们的手势是“交互式的”。用户的手势控制动画。据我所知,还没有人真正想到开源,但理论上应该可以使用 Pop/AsyncDisplayKit。
    • @chug2k 通过使用setTransitionProgress:time: 方法绝对可以使用github.com/wtmoose/TLLayoutTransitioning。我们过去使用上述 OSP 实现了类似的功能。
    【解决方案3】:

    我采用了解决方案here 并对其稍作修改以使用集合视图。我还添加了一个透明的灰色背景来稍微隐藏原始视图(假设图像没有占据整个框架)。

    @implementation CollectionViewController
    {
        UIImageView *fullScreenImageView;
        UIImageView *originalImageView;
    }
    
    ...
    
    // in whatever method you're using to detect the cell selection
    
    CGPoint pointInCollectionView = [gesture locationInView:self.collectionView];
    NSIndexPath *selectedIndexPath = [self.collectionView indexPathForItemAtPoint:pointInCollectionView];
    UICollectionViewCell *selectedCell = [self.collectionView cellForItemAtIndexPath:selectedIndexPath];
    
    originalImageView = [selectedCell imageView]; // or whatever cell element holds your image that you want to zoom
    
    fullScreenImageView = [[UIImageView alloc] init];
    [fullScreenImageView setContentMode:UIViewContentModeScaleAspectFit];
    
    fullScreenImageView.image = [originalImageView image];
    // ***********************************************************************************
    // You can either use this to zoom in from the center of your cell
    CGRect tempPoint = CGRectMake(originalImageView.center.x, originalImageView.center.y, 0, 0);
    // OR, if you want to zoom from the tapped point...
    CGRect tempPoint = CGRectMake(pointInCollectionView.x, pointInCollectionView.y, 0, 0);
    // ***********************************************************************************
    CGRect startingPoint = [self.view convertRect:tempPoint fromView:[self.collectionView cellForItemAtIndexPath:selectedIndexPath]];
    [fullScreenImageView setFrame:startingPoint];
    [fullScreenImageView setBackgroundColor:[[UIColor lightGrayColor] colorWithAlphaComponent:0.9f]];
    
    [self.view addSubview:fullScreenImageView];
    
    [UIView animateWithDuration:0.4
                     animations:^{
                         [fullScreenImageView setFrame:CGRectMake(0,
                                                       0,
                                                       self.view.bounds.size.width,
                                                       self.view.bounds.size.height)];
                     }];
    
    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(fullScreenImageViewTapped:)];
    singleTap.numberOfTapsRequired = 1;
    singleTap.numberOfTouchesRequired = 1;
    [fullScreenImageView addGestureRecognizer:singleTap];
    [fullScreenImageView setUserInteractionEnabled:YES];
    
    ...
    
    - (void)fullScreenImageViewTapped:(UIGestureRecognizer *)gestureRecognizer {
    
        CGRect point=[self.view convertRect:originalImageView.bounds fromView:originalImageView];
    
        gestureRecognizer.view.backgroundColor=[UIColor clearColor];
        [UIView animateWithDuration:0.5
                         animations:^{
                             [(UIImageView *)gestureRecognizer.view setFrame:point];
                         }];
        [self performSelector:@selector(animationDone:) withObject:[gestureRecognizer view] afterDelay:0.4];
    
    }
    
    -(void)animationDone:(UIView  *)view
    {
        [fullScreenImageView removeFromSuperview];
        fullScreenImageView = nil;
    }
    

    【讨论】:

    • 太棒了。这就是我一直在寻找的。奇迹般有效。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 2018-03-31
    • 2011-04-30
    • 2012-05-20
    • 1970-01-01
    • 2014-12-18
    相关资源
    最近更新 更多