Могу ли я анимировать свойство contentOffset UIScrollView через его слой? - PullRequest
24 голосов
/ 30 июня 2011

Я хочу увеличить масштаб и прокрутить UIScrollView с помощью CGPathRef. Из-за этого я предполагаю, что мне нужно анимировать свойство layer UIScrollView? Но какое свойство я бы анимировал, чтобы сделать его эквивалентным выполнению анимации UIView и установке его свойств contentOffset и zoomScale?

Это не свойства CALayer.

Есть идеи, как бы я подошел к этому? Опять же, просто нужно переместить представление прокрутки к определенному contentOffset и zoomScale, но необязательно линейно из точки A в точку B, масштаб A для увеличения B, соответственно.

Я думал о анимации CAKeyFrame с CGPathRef, но я не знаю, какие свойства анимировать.

Ответы [ 3 ]

54 голосов
/ 05 января 2012

Вы должны анимировать свойство 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=<CABasicAnimation: 0xec1e7c0>; }.

Надеюсь, это поможет.

0 голосов
/ 21 марта 2019

Swift 4.2

Этот пример основан на obj-c ответе pt2ph8.

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
}
0 голосов
/ 10 октября 2011

Перемещение CALayer осуществляется (предпочтительно) путем установки его свойства .position - или, возможно, anchorPoint (см. Документы по этому вопросу: http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html).

... но я не думаю, что вы хотите связываться с CALayer, если вы работаете с UIScrollView. Вы пытались применить простые CoreAnimations к вашему ScrollView?

(проблема в том, что UIScrollView реализован поверх CALayer - так что, даже если вы сможете взломать его для работы сегодня, вполне вероятно, что он сломается в будущих версиях iOS. Если возможно, вы хотите избежать CALayer для этого класс)

...