9

我有一个 iPad 应用程序,我在其中使用 UICollectionView,每个 UICollectionViewCell 只包含一个 UIImage。目前我每页显示每 9 个 UIImages(3 行 * 3 列),我有几页。

我想使用 Pinch Gesture 缩放整个 UICollectionView 以增加/减少每页显示的行/列数,最好是在 Pinch 手势期间有漂亮的缩放动画!

目前,我在 UICollectionView 上添加了捏合手势。我捕获 Pinch Gesture 事件以使用比例因子计算行/列数,如果它已更改,则我使用以下方法更新完整的 UICollectionView:

[_theCollectionView performBatchUpdates:^{
     [_theCollectionView deleteSections:[NSIndexSet indexSetWithIndex:0]];
     [_theCollectionView insertSections:[NSIndexSet indexSetWithIndex:0]];
 } completion:nil];

它可以工作,但在过渡期间我没有流畅的动画。

任何想法?UICollectionView 继承自 UIScrollView,是否有可能重新使用 UIScrollView Pinch 手势功能来达到我的目标?

4

3 回答 3

30

我假设您使用的是默认的 UICollectionViewDelegateFlowLayout,对吧?然后确保您对委托方法做出相应的响应,并且当出现捏合手势时,只需使布局无效。

例如,如果我想调整每个项目的大小,同时捏:

@interface ViewController () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>

@property (nonatomic,assign) CGFloat scale;
@property (nonatomic,weak)   IBOutlet UICollectionView *collectionView;

@end

@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];

    self.scale = 1.0;

    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cell"];

    UIPinchGestureRecognizer *gesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(didReceivePinchGesture:)];
    [self.collectionView addGestureRecognizer:gesture];

}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
    return CGSizeMake(50*self.scale, 50*self.scale);
}

- (void)didReceivePinchGesture:(UIPinchGestureRecognizer*)gesture
{
    static CGFloat scaleStart;

    if (gesture.state == UIGestureRecognizerStateBegan)
    {
        scaleStart = self.scale;
    }
    else if (gesture.state == UIGestureRecognizerStateChanged)
    {
        self.scale = scaleStart * gesture.scale;
        [self.collectionView.collectionViewLayout invalidateLayout];
    }
}

该属性self.scale仅用于展示,您可以将相同的概念应用于任何其他属性,这不需要 beginUpdates/endUpdates 因为用户自己携带刻度的时间。

这是一个正在运行的项目,如果您想查看它的运行情况。

于 2013-07-08T02:01:14.397 回答
1

对不起我的 2 美分问题,我找到了解决方案,非常简单。

在我的PinchGesture回调中,我刚刚完成了以下操作:

void (^animateChangeWidth)() = ^() {
    _theFlowLayout.itemSize = cellSize;
};

[UIView transitionWithView:self.theCollectionView 
                  duration:0.1f 
                   options:UIViewAnimationOptionCurveLinear 
                animations:animateChangeWidth 
                completion:nil];

我的所有单元格UICollectionView都已成功更改,并且transition.

于 2013-05-06T22:14:02.190 回答
0

对于 Xamarin.iOS 开发人员,我找到了这个解决方案:将 UIScrollView 元素添加到主视图并将 UICollectionView 添加为 UIScrollView 的元素。然后为 UIScrollView 创建一个缩放委托。

MainScrollView = new UIScrollView(new CGRect(View.Frame.X, View.Frame.Y, size.Width, size.Height));

        
        _cellReuseId = GenCellReuseId();

        _contentScroll = new UICollectionView(new CGRect(View.Frame.X, View.Frame.Y, size.Width, size.Height), new InfiniteScrollCollectionLayout(size.Width, size.Height));
        
        _contentScroll.AllowsSelection = true;
        _contentScroll.ReloadData();


        _contentScroll.Center = MainScrollView.Center;
        _contentScroll.Frame = new CGRect(_contentScroll.Frame.X, _contentScroll.Frame.Y - 32, _contentScroll.Frame.Width, _contentScroll.Frame.Height);
        MainScrollView.ContentSize = _contentScroll.ContentSize;
        MainScrollView.AddSubview(_contentScroll);
        MainScrollView.MaximumZoomScale = 4f;
        MainScrollView.MinimumZoomScale = 1f;
        MainScrollView.BouncesZoom = true;
        MainScrollView.ViewForZoomingInScrollView += (UIScrollView sv) =>
        {
            if (_contentScroll.Frame.Height < sv.Frame.Height && _contentScroll.Frame.Width < sv.Frame.Width)
            {
                _contentScroll.Center = MainScrollView.Center;
                _contentScroll.Frame = new CGRect(_contentScroll.Frame.X, _contentScroll.Frame.Y - 64, _contentScroll.Frame.Width, _contentScroll.Frame.Height);
                _contentScroll.BouncesZoom = true;
                _contentScroll.AlwaysBounceHorizontal = false;
            }
            return _contentScroll;
};
于 2020-03-27T09:29:28.463 回答