如何缩放UICollectionViewCell中的UIScrollView?

我正在尝试在UICollectionViewCell添加一个UIScrollView 。 这个想法是,你可以使用捏来缩放UIScrollView (和它,图像内),但滚动视图似乎不处理任何手势。 我猜他们正在被UICollectionView

我已经将UIScrollView的委托设置为UICollectionViewCell ,但是没有一个委托方法正在被调用。

编辑:我做了一个github回购代码(尽可能简化我)。 即使这只是几行代码,我看不出我做错了什么。

编辑2:答案被发现后,我join了上述回购修复,希望别人也发现它也有帮助:)

https://github.com/krummler/gallery-pinchzoom-example

您可能需要尝试操作UIGestureRecognizers才能完成此操作。 在GalleryViewController

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { GalleryImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"galleryImageCell" forIndexPath:indexPath]; ImageContext *imageContext = [self.images objectAtIndex:indexPath.row]; cell.imageContext = imageContext; [self.collectionView addGestureRecognizer:cell.scrollView.pinchGestureRecognizer]; [self.collectionView addGestureRecognizer:cell.scrollView.panGestureRecognizer]; return cell; } 

从UIView的Apple文档 :

将手势识别器附加到视图可以定义所表示的手势的范围,使其接受对该视图及其所有子视图进行了testing的触摸。 视图保留手势识别器。

所以你也想确保当单元格不再显示时将它们移除。

 - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath { // Get the cell instance and ... [self.collectionView removeGestureRecognizer:cell.scrollView.pinchGestureRecognizer]; [self.collectionView removeGestureRecognizer:cell.scrollView.panGestureRecognizer]; } 

既然你没有修改UIGestureRecognizer的委托,只有它的范围,它仍然会控制单元格的滚动视图的缩放。

编辑

在OP的build议之后,我将panGestureRecognizer添加到了上面的例子中。 缩放本身完全由pinchGestureRecognizer处理,但是在大多数情况下,在将图像缩放到只有一部分可见的点后,您需要平移以移动可见部分。 也就是说,这是适当的缩放体验的一部分。

我只是在iOS 9.3+上为SWIFT 3做了一个实现,而我所做的只是:

1.将图像视图放在滚动视图中

故事板的例子

2.将scrollview委托连接到collectionview单元类

3.在collectionview子类上实现下面的代码

 class FullScreenImageTextDetailCollectionViewCell: UICollectionViewCell, UIScrollViewDelegate { @IBOutlet var scrollview: UIScrollView! @IBOutlet weak var backgroundImageView: UIImageView! override func awakeFromNib() { self.scrollview.minimumZoomScale = 0.5 self.scrollview.maximumZoomScale = 3.5 self.scrollview.delegate = self } func viewForZooming(in scrollView: UIScrollView) -> UIView? { return self.backgroundImageView } } 

没有手势识别器添加或删除父级collectionview控制器是必要的,工作就像一个魅力!

感谢以前的例子达到这个!

请在您的单元格中添加滚动视图,并在滚动视图中添加当前的单元格图像视图。 然后使用下面的代码:

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { ImageContext *context = [self.images objectAtIndex:indexPath.row]; ImageCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"imageCell" forIndexPath:indexPath]; cell.cellScrollView.autoresizesSubviews = YES; cell.cellScrollView.multipleTouchEnabled =YES; cell.cellScrollView.maximumZoomScale = 4.0; cell.cellScrollView.minimumZoomScale = 1.0; cell.cellScrollView.clipsToBounds = YES; cell.cellScrollView.delegate = self; cell.cellScrollView.zoomScale = 1.0; [cell.imageView setImage:[UIImage imageNamed:context.thumbImageUrl]]; return cell; } -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { NSLog(@"%i",scrollView.subviews.count); for (UIView *v in scrollView.subviews) { if ([v isKindOfClass:[UIImageView class]]) { return v; } } 

}

检查所有相关视图的多点触控是否打开。 iOS在大多数视图上默认禁用多点触控,以节省能源。

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if (touch.view == [self myScrollView]) //<- whatever your scrollView is called { return YES; } return NO; } 

不知道你的代码,但尝试玩上面的代码,看看你是否可以筛选你想要的对象触摸。 以上代码来自UIGestureRecognizerDelegate协议参考 。

代表不会被调用,因为你在UICollectionView中添加了它。触摸事件对于集合视图来说是可用的,这是超视图,因此无法通过视图获得。您可能需要想办法实现这个模型。

UICollectionViewUITableView具有相同的模式,这个问题出现在scrollview的tableview中,触摸事件被scrollview [ 这是 superview]接受,并使tableview在这种情况下是可滚动的,scrollview的scroll必须被禁用。是这个问题的另一个版本

苹果的文件说,上述案件做出不可预知的结果。所以这可能是相同的问题。

在我看来,你必须去更好的devise,可以实现你所期待的

 I've set the delegate of the UIScrollView to be the UICollectionViewCell, but none of the delegate methods are being called. 

为此只需在collectionViewCell中定义一个函数

  @IBOutlet weak var mainScrollView:UIScrollView! func setup(){ mainScrollView.minimumZoomScale=1 mainScrollView.maximumZoomScale=10.0 mainScrollView.delegate=self } func viewForZooming(in scrollView: UIScrollView) -> UIView? { return yourimageviewinside of scrollview } 

collectionview(_,cellForItem )方法中调用这个函数