如何在 UICollectionViewCell 内缩放 UIScrollView?
Posted
技术标签:
【中文标题】如何在 UICollectionViewCell 内缩放 UIScrollView?【英文标题】:How to zoom a UIScrollView inside of a UICollectionViewCell? 【发布时间】:2013-06-06 11:07:32 【问题描述】:我正在尝试在 UICollectionViewCell
中添加 UIScrollView
。这个想法是您可以使用捏缩放UIScrollView
(以及其中的图像),但滚动视图似乎不处理任何手势。我猜他们被UICollectionView
抓住了。
我已将UIScrollView
的委托设置为UICollectionViewCell
,但没有调用任何委托方法。
编辑: 我用代码制作了一个 github repo(尽可能简化)。虽然只是几行代码,但我看不出我做错了什么。
EDIT2:找到答案后,我将修复添加到上述存储库中,希望其他人也觉得它有帮助:)
https://github.com/krummler/gallery-pinchzoom-example
【问题讨论】:
感谢您将更新的代码放入存储库。这对我很有用! 链接已损坏。请更新链接 【参考方案1】:我刚刚在 iOS 9.3+ 上实现了 SWIFT 3,我所做的只是:
1.将图像视图放在滚动视图中
2。将滚动视图委托连接到 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控制器上添加或删除手势识别器,就像一个魅力!
感谢之前的示例!
【讨论】:
很好的答案。将 viewForZooming 委托回调放在 cell 类中是关键。 您能否为此提供 .swift 和 .xib 文件。这似乎很简单,但我无法让它最终发挥作用。【参考方案2】:您可能想尝试操作 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;
来自Apple's documentation on UIView:
将手势识别器附加到视图定义了所表示手势的范围,使其接收对该视图及其所有子视图进行命中测试的触摸。视图保留了手势识别器。
因此,您还需要确保在单元格不再显示时将其删除。
- (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 的建议,我将 panGestureRecognizer
添加到上述示例中。缩放本身完全由pinchGestureRecognizer
处理,但确实在大多数情况下,在将图像缩放到只有一部分可见的点之后,您需要平移以移动可见部分。也就是说,它是适当缩放体验的一部分。
【讨论】:
太棒了!我必须为panGestureRecognizer
做同样的事情,我很高兴!谢谢 :) (由于某种原因无法奖励赏金,我会稍后再做。)
@matehat 我使用 swift 和我的 didEndDisplaying 单元格,我不断收到“发现 nil unwrapping optional”错误。我试过让它'如果让',它永远不会被调用。 :/这是我获取实例的方式:let cell = collectionView.cellForItemAtIndexPath(indexPath) as! FSImageCell
我不需要在单元格中添加/删除手势识别器。捏合和平移都已经在单元格中为我工作,同时仍然允许我水平滚动浏览我的收藏视图。我在图片库中使用全屏单元格。【参考方案3】:
请在您的单元格中添加滚动视图,并将您当前的单元格图像视图添加到滚动视图中。 然后使用下面的代码:
- (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;
【讨论】:
【参考方案4】:检查所有相关视图的多点触控是否开启。 ios 在大多数视图上默认禁用多点触控以节省能源。
【讨论】:
我试过了,并试图模仿一些我能找到的例子,但我仍然无法让它工作。我在原始帖子中添加了一个 github repo url【参考方案5】:- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
if (touch.view == [self myScrollView]) //<- whatever your scrollView is called
return YES;
return NO;
不知道您的代码,但请尝试使用上面的代码,看看您是否可以过滤您对所需对象的触摸。以上代码来自UIGestureRecognizerDelegate Protocol Reference。
【讨论】:
谢谢,我在collectionviewcell中添加了,里面好像没有为scrollview调用,只为outer view调用。【参考方案6】:代理没有被调用,因为您在 UICollectionview 中添加了它。触摸事件可用于作为超级视图的集合视图,因此无法通过内部视图获得。您可能需要考虑其他一些方法来实现这个模型。
UICollectionView
与UITableView
具有相同的模式,问题出现在滚动视图内的表格视图中,滚动视图[这是超级视图] 接受触摸事件并制作表格视图在这种情况下可滚动,必须禁用滚动视图的滚动。这是该问题的另一个版本
苹果文档说上述情况会产生不可预测的结果。所以这可能与您的问题相同。
在我看来,您必须寻求更好的设计,以实现您的目标
【讨论】:
【参考方案7】: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 )
collectionview的方法
【讨论】:
以上是关于如何在 UICollectionViewCell 内缩放 UIScrollView?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 7 中刷新 UICollectionViewCell?
如何在 UICollectionViewCell 内缩放 UIScrollView?
如何在重新加载时清除 UICollectionViewCell?
Swift:如何在 UICollectionViewCell 中使用“prepareForSegue”?