内容偏移动画损坏
Posted
技术标签:
【中文标题】内容偏移动画损坏【英文标题】:Content Offset animation broken 【发布时间】:2014-03-05 14:30:30 【问题描述】:我有一个在手势识别器(双击)触发时启动的动画:
[UIView animateWithDuration:0.3 animations:^
_scrollView.contentOffset = CGPointMake(x, y);
_scrollViewContentView.frame = someFrame;
_scrollViewContentView.layer.transform =
CATransform3DMakeScale(1.f/_zoomScale, 1.f/_zoomScale, 1.f);
];
它工作得很好,除了在一种情况下:如果在动画执行之前没有调用scrollViewWillBeginDecelerating
委托方法(只是通过几乎不拖动我的滚动视图)。
我刚刚调用了scrollViewDidEndDragging
方法。我可以等待20 秒然后播放我的动画。除了我的contentOffset
之外,它将正常播放。
委托方法本身什么都不做,它们只是被添加来看看问题可能出在哪里。
我不知道为什么。
编辑:这是我的问题的video。第 1 阶段:减速滚动,第 2 阶段没有。看看最后的位置。阶段1是正确的但不是阶段
【问题讨论】:
你是说有时不调用scrollViewWillBeginDecelerating? 不,这很正常。我直接停止滚动,因此不会产生减速效果。所以当我这样做时,我的动画就坏了。但我的手势有减速暗示它有效。不知道我是否清除... 请您更新您的问题以显示您在何时何地调用此动画? 我的意思是你调用它的方法,但视频确实有帮助! 我滚动并在之后(可能是 2 秒或 10 分钟)我从一个手势(UITapGesture 双击)启动我的动画块。 【参考方案1】:尝试:
[_scrollView setContentOffSet:CGPointMake(x, y) animated:YES];
在动画块之外。我不相信 contentOffSet 可以通过 UIView 的动画块设置动画。
编辑: 而不是:
_scrollview.contentOffSet = CGPointMake(x, y);
尝试:
_scrollview.bounds = CGRectMake(x, y, CGRectGetWidth(scrollview.bounds), CGRectGetHeight(scrollview.bounds));
【讨论】:
不,因为它在减速滚动后在我的块内工作。没有减速就坏了。即使我这样做,结果对用户来说也不会那么好(不同的持续时间,因为我的是一个常量,而 setContentView:animated: 不是) 嗯,好吧...我仍然觉得我不完全理解您遇到的问题。但是为 contentOffSet 设置动画的另一种方法是为边界设置动画。如果你在编辑时尝试代码,会发生什么? 谢谢,但结果相同。看我的视频;)【参考方案2】:我怀疑这行中的 x 可能会导致您看到的效果:
_scrollView.contentOffset = CGPointMake(x, y);
它有什么价值?我认为您应该尝试用 CGPointMake(0, y) 替换它,看看是否会导致每次出现白边。
我的理由如下:
1) 要创建不超出图像范围(不显示白色背景)的弹跳效果,您必须将_scrollView
的contentSize.width
设置为小于实际图像大小。
2) 要允许滚动,您将contentSize.width
设置为大于_scrollView
的宽度
3) 您已将_scrollView
中的图像相对于contentSize
的大小居中
4) 制作动画时,您可能正在使用预先计算的 x 坐标设置框架以将图像定位在左侧尺寸上,因为没有那个 CATransform3DMakeScale
只会将图像留在中心(顺便说一下,为什么使用 CATransform3DMakeScale
,你什么时候可以改变框架的大小?)
5) 在视频中,第一次运行动画时,您将 contentOffset.x
设置为最大值(因为您向左拖动,因此增加了内容偏移量,并且滚动视图反弹回它的最大内容偏移量) t 超出内容大小限制)
6) 在视频中第二次运行动画时,contentOffset.x
的值较小,因为您通过减小它向右拖动
7) 动画完成后,scrollView 的内容大小仍然相同,因此可用滚动量相同。如果 contentOffset.x
的最大值为最大值,则左侧的图像会更多,如果 contentOffset.x 的值较小 - 右侧的图像会更多
8) 如果_scrollView.contentOffset = CGPointMake(x, y);
中的 x 与动画之前的实际内容偏移有关,那么在第一种情况下图像更多出现在左侧,而在第二种情况下更多出现在右侧,这是有道理的。
如果我是对的,那么这就是你可以解决的方法:
a) 如果您希望图像始终出现在特定的 x 位置,请确保在动画中设置常量 contentOffset。
b) 根据您要制作动画的 contentOffset 调整计算帧 (someFrame
) 原点的代码(看起来现在它只适用于最大 contentOffset.x)。
c) 如果在动画之后您不希望内容可滚动,请确保在动画块中设置_scrollView.contentSize = _scrollview.bounds.size;
。
【讨论】:
【参考方案3】:我不确定我是否完全理解你的问题(也许你可以试着解释一下你想在这个动画中完成什么?)。无论如何,也许试试这个而不是使用setContentOffset
:
CGRect *rect = CGRectMake(x, y, 0, 0);
[_scrollView scrollRectToVisible:rect animated:YES];
【讨论】:
【参考方案4】:也许尝试使用核心动画而不是 UIView 动画。如果您遇到麻烦的原因是因为所有动画都从图层中删除,那不会有什么不同,但如果是由于-[removeAnimationForKey:@"bounds"]
,这可能是赢家。
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
animation.fromValue = [NSValue valueWithCGRect:_scrollView.layer.bounds];
animation.toValue = [NSValue valueWithCGRect:(CGRect) .origin = CGPointMake(x,y), .size = scrollView.layer.bounds.size ];
[scrollView.layer addAnimation:animation forKey:@"myCustomScroll"];
scrollView.layer.bounds = (CGRect) .origin = CGPointMake(x,y), .size = scrollView.layer.bounds.size ;
附:我还没有测试上面的代码,这只是我的想法,所以对任何愚蠢的错误表示歉意。
【讨论】:
关键路径是bounds
并且您正在为该值设置一个点,这将是愚蠢的错误 #1 ;)
啊,是的,我的错误。因此免责声明。以上是关于内容偏移动画损坏的主要内容,如果未能解决你的问题,请参考以下文章