我可以通过其图层对 UIScrollView contentOffset 属性进行动画处理吗?

发布于 2024-11-17 16:20:26 字数 337 浏览 7 评论 0原文

我想使用 CGPathRef 缩放和滚动 UIScrollView。因此,我认为我必须为 UIScrollView 的图层属性设置动画?但是我应该对哪个属性进行动画处理,使其相当于执行 UIView 动画并设置其 contentOffset 属性和 ZoomScale ?

这些不是 CALayer 的属性。

关于我如何处理这个问题有什么想法吗?还是那句话,只是想将scrollview移动到某个contentOffset和zoomScale,但不一定是线性地分别从A点到B点,缩放A到缩放B。

我正在考虑使用 CGPathRef 的 CAKeyFrameAnimation,但我不知道要对哪些属性进行动画处理。

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 ?

These are not properties of a 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.

I was thinking a CAKeyFrameAnimation with a CGPathRef, but I don't know which properties to animate.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

日久见人心 2024-11-24 16:20:26

您必须为 bounds 属性设置动画。事实上,这就是 contentOffset 属性在幕后使用的内容。

示例:

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;

如果您好奇,我用来获取此信息的方式如下:

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];

[scrollView setContentOffset:CGPointMake(200, 0) animated:NO];

[UIView commitAnimations];

NSLog(@"%@",scrollView);

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}>

animations 代码段将列出所有活动动画,在这种情况下 {bounds=; }

希望这有帮助。

You have to animate the bounds property. In fact, that's what the contentOffset property uses behind the scenes.

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:

<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>; }.

Hope this helps.

ぇ气 2024-11-24 16:20:26

移动 CALayer 是通过(最好)设置它的 .position 属性来完成的 - 或者可能是anchorPoint(参见相关文档:http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html)。

...但我认为如果您使用 UIScrollView,您不想弄乱 CALayer。您是否尝试过将普通 CoreAnimations 应用于 ScrollView?

(问题是:UIScrollView 是在 CALayer 之上实现的 - 所以即使你现在可以破解它来工作,它很可能在未来的 iOS 版本中崩溃。如果可能的话,你想避免该特定类的 CALayer)

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 ).

...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?

(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)

如日中天 2024-11-24 16:20:26

Swift 4.2

此示例基于 pt2ph8 的 obj-c 答案。

https://stackoverflow.com/a/8741283/6113158

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
}

Swift 4.2

This example is base on pt2ph8's obj-c answer.

https://stackoverflow.com/a/8741283/6113158

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文