设置:
我UIScrollView
在班级的帮助下设置了水平分页LXPagingViews
(以轻松添加 'peeping' UIScrollView
)。这是设置好的,因此您可以在UIScrollView
. 我UIPinchGestureRecognizer
为每个视图添加了一个,所以当用户捏住一个视图时,它会显示一个“缩放”动画,并进入详细视图。更清晰的屏幕截图:
问题:
当我捏住其中一个视图时,缩放动画开始,视图进入详细视图。这工作正常,除了UIScrollView
. 在最后一个视图中(不管它有多少视图,只要它有超过 2 个),当动画播放时,它会在我点击的视图后面生成一个新视图,并为该视图设置动画。这产生了一个奇怪的动画。此外,动画不会阻止视图输入,因为它会生成一个新视图。这意味着用户可以通过快速捏合来快速生成多个视图。
我希望这个屏幕截图能稍微说明问题:
我试过的:
- 调试手势识别器的超级视图子视图,以查看是否产生更多视图
- 监控哪些视图获得了动画效果。对于用户所做的每一次捏合,由于某种原因,另一个视图会被动画化
- 尝试使用另一种设置图像的方式而不是延迟加载。没有帮助
- 尝试了其他图像,越来越少的视图,方向差异和空视图。
代码:
将手势识别器添加到视图中:
- (UIView<ReusableView> *)pagingView:(PagingView *)thePagingView reusableViewForPageIndex:(NSUInteger)thePageIndex withFrame:(CGRect)theFrame {
// View's Identifier
static NSString *theIdentifier = @"voucherDetailView";
VoucherDetailView *thePageView = (VoucherDetailView *)[thePagingView dequeueReusableViewWithIdentifier:theIdentifier];
if (thePageView == nil) {
thePageView = [[VoucherDetailView alloc] initWithFrame:theFrame];
} else {
thePageView.frame = theFrame;
}
Voucher *voucher = [_vouchers objectAtIndex:thePageIndex];
NSURL *fullVoucherImageUrl = [NSURL URLWithString:voucher.fullVoucherImage];
[thePageView.voucher setImageWithURL:fullVoucherImageUrl placeholderImage:[UIImage imageNamed:@"11283253-nederland_kaart"]];
// Gesture recognizer
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(openZoomablePinch:)];
[thePageView addGestureRecognizer:pinchGesture];
return thePageView;
}
夹点处理程序:
- (void)openZoomablePinch:(UIPinchGestureRecognizer*)sender {
// Only allow one pinch to activate the animation
if (sender.state == UIGestureRecognizerStateBegan) {
// Bring the view to the front so it doesn't clip with the peeping views
[sender.view.superview bringSubviewToFront:sender.view];
CGAffineTransform trans = sender.view.transform;
[UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveEaseOut
animations:^{
sender.view.transform = CGAffineTransformScale(sender.view.transform, 1.15, 1.15);
}
completion:^(BOOL finished) {
if (finished && self.view.window) {
sender.view.transform = trans;
[self performSegueWithIdentifier:@"voucherZoomSegue" sender:self];
}
}];
}
}
编辑:捏时在最后一个视图上调用的 PagingView 代码:
UIView<ReusableView> *theRightMostReusableView = [self.visibleReusableViews lastObject];
NSUInteger theRightMostPageIndex = (NSUInteger)floorf(CGRectGetMinX(theRightMostReusableView.frame) / thePageWidth);
while ((theRightMostPageIndex != MAX(0, self.numberOfItems - 1)) && (theRightMostPageIndex < theToIndex)) {
theRightMostPageIndex = MIN(theRightMostPageIndex + 1, MAX(0, self.numberOfItems - 1));
CGFloat theMinX = theRightMostPageIndex * thePageWidth;
CGRect theRect = CGRectMake(theMinX, 0.0f, thePageWidth, thePageHeight);
UIView<ReusableView> *theReusableView = [self.dataSource pagingView:self reusableViewForPageIndex:theRightMostPageIndex withFrame:theRect];
if (!CGRectContainsRect(theRect, theReusableView.frame)) {
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:
@"theReusableView's frame (%@) must be contained by the given frame (%@)",
NSStringFromCGRect(theReusableView.frame),
NSStringFromCGRect(theRect)]
userInfo:nil];
}
[self.visibleReusableViews addObject:theReusableView];
[self addSubview:theReusableView];
}
编辑2:
我在这里上传了一个小演示项目。使用它的方法,将模拟器(或您的设备)设置为横向,转到 Peeping Paging View,然后尝试捏/点击视图(第一个视图除外)。如您所见,视图被缩放,除了最后一个视图,它在其后面生成一个新视图并缩放该视图(“9”保持相同大小)。
代码在PeepingPagingViewController.m
.
解决方案(感谢 Oladya Kane):
最右边的可见索引被错误地索引为最左边的可见索引。我必须更改的代码是以下行:
NSUInteger theRightMostPageIndex = (NSUInteger)floorf(CGRectGetMinX(theRightMostReusableView.frame) / thePageWidth);
到
NSUInteger theRightMostPageIndex = MIN((NSInteger)floorf((CGRectGetMaxX(theRightMostReusableView.frame) - 0.1f) / thePageWidth), MAX(0, self.numberOfItems - 1));