我有一个iPad应用程序,我正在使用UICollectionView,每个UICollectionViewCell只包含一个UIImage。 目前我每页显示9个UIImages(3行* 3列),我有几页。
我想使用Pinch Gesture缩放整个UICollectionView来增加/减少每页显示的行数/列数,最好是在Pinch手势中获得漂亮的缩放动画!
目前,我在我的UICollectionView上添加了一个Pinch Gesture。我捕获了Pinch Gesture事件以使用比例因子计算行数/列数,如果它已更改,则使用以下命令更新完整的UICollectionView:
[_theCollectionView performBatchUpdates:^{
[_theCollectionView deleteSections:[NSIndexSet indexSetWithIndex:0]];
[_theCollectionView insertSections:[NSIndexSet indexSetWithIndex:0]];
} completion:nil];
它有效,但在转换期间我没有平滑的动画。
有什么想法吗? UICollectionView继承自UIScrollView,是否有可能重用UIScrollView Pinch手势功能来实现我的目标?
答案 0 :(得分:27)
我假设你正在使用默认的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,因为用户自己正在进行比例的计时。
Here's a running project,以防您希望在行动中看到它。
答案 1 :(得分:1)
对不起我的2美分问题,我找到了解决方案,非常简单。
在我的PinchGesture
回调中,我刚刚完成了以下操作:
void (^animateChangeWidth)() = ^() {
_theFlowLayout.itemSize = cellSize;
};
[UIView transitionWithView:self.theCollectionView
duration:0.1f
options:UIViewAnimationOptionCurveLinear
animations:animateChangeWidth
completion:nil];
我UICollectionView
的所有单元格都已成功更改并且有一个很好的transition
。
答案 2 :(得分: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;
};