ios 我可以通过其图层为 UIScrollView contentOffset 属性设置动画吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6535450/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I animate the UIScrollView contentOffset property via its layer?
提问by horseshoe7
I want to zoom and scroll a UIScrollView with a CGPathRef. Because of that I assume I have to animate the UIScrollView's layer property? But which property would I animate that would make it equivalent to doing a UIView animation and setting its contentOffset property and zoomScale ?
我想用 CGPathRef 缩放和滚动 UIScrollView。因此,我假设我必须为 UIScrollView 的图层属性设置动画?但是我会为哪个属性设置动画,使其等同于执行 UIView 动画并设置其 contentOffset 属性和 zoomScale ?
These are not properties of a CALayer.
这些不是 CALayer 的属性。
Any ideas as to how I would approach this? Again, just want to move the scrollview to a certain contentOffset and zoomScale, but not necessarily linearly from point A to point B, zoom A to zoom B, respectively.
关于我将如何解决这个问题的任何想法?同样,只是想将滚动视图移动到某个 contentOffset 和 zoomScale,但不一定分别从 A 点到 B 点线性缩放,缩放 A 到缩放 B。
I was thinking a CAKeyFrameAnimation with a CGPathRef, but I don't know which properties to animate.
我在想一个带有 CGPathRef 的 CAKeyFrameAnimation,但我不知道要为哪些属性设置动画。
回答by pt2ph8
You have to animate the bounds
property. In fact, that's what the contentOffset
property uses behind the scenes.
您必须为该bounds
属性设置动画。事实上,这就是该contentOffset
属性在幕后使用的内容。
Example:
例子:
CGRect bounds = scrollView.bounds;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];
animation.duration = 1.0;
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.fromValue = [NSValue valueWithCGRect:bounds];
bounds.origin.x += 200;
animation.toValue = [NSValue valueWithCGRect:bounds];
[scrollView.layer addAnimation:animation forKey:@"bounds"];
scrollView.bounds = bounds;
If you're curious, the way I used to get this information is the following:
如果你很好奇,我过去获取这些信息的方式如下:
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[scrollView setContentOffset:CGPointMake(200, 0) animated:NO];
[UIView commitAnimations];
NSLog(@"%@",scrollView);
The NSLog
call will output:
的NSLog
通话将输出:
<UIScrollView: 0x860ba20; frame = (-65.5 0; 451 367); clipsToBounds = YES; autoresize = W+RM+TM+H; animations = { bounds=<CABasicAnimation: 0xec1e7c0>; }; layer = <CALayer: 0x860bbc0>; contentOffset: {246, 0}>
The animations
snippet will list all the active animations, in this case { bounds=<CABasicAnimation: 0xec1e7c0>; }
.
该animations
代码段将列出所有活动动画,在本例中为{ bounds=<CABasicAnimation: 0xec1e7c0>; }
。
Hope this helps.
希望这可以帮助。
回答by Adam
Moving a CALayer around is done by (preferably) setting it's .position property - or possibly the anchorPoint (c.f. the docs on that: http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html).
移动 CALayer 是通过(最好)设置它的 .position 属性来完成的 - 或者可能是 anchorPoint (参见文档:http: //developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/介绍/介绍.html)。
...but I don't think you want to mess with the CALayer if you're working with a UIScrollView. Have you tried applying plain CoreAnimations to your ScrollView?
...但我认为如果您正在使用 UIScrollView,您不会想弄乱 CALayer。您是否尝试过将普通 CoreAnimations 应用于您的 ScrollView?
(the problem is: the UIScrollView is implemented on top of CALayer - so even if you can hack it to work today, it's quite likely to break in future iOS versions. If possible, you want to avoid the CALayer for that particular class)
(问题是:UIScrollView 是在 CALayer 之上实现的——所以即使你今天可以破解它,它也很可能在未来的 iOS 版本中崩溃。如果可能,你想避免该特定类的 CALayer)
回答by alex02rt
Swift 4.2
斯威夫特 4.2
This example is base on pt2ph8's obj-c
answer.
此示例基于 pt2ph8 的obj-c
答案。
var scrollView = UIScrollView()
func animateScrollView(duration: Double, to newBounds: CGRect) {
let animation = CABasicAnimation(keyPath: "bounds")
animation.duration = duration
animation.fromValue = scrollView.bounds
animation.toValue = newBounds
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
scrollView.layer.add(animation, forKey: nil)
scrollView.bounds = newBounds
}