我需要密切监视滚动视图的缩放,以便根据滚动视图的动画缩放更新内容视图的元素(管理多个CALayers的子视图)。
在iOS 3.1上,一切都按预期工作,我使用zoomToRect: UIScrollViewDelegate:和scrollViewDidScroll: message of UIScrollViewDelegate在动画进行时反复调用,允许我根据实际缩放更新子视图元素。
iOS 4.0上的相同代码不存在相同的行为。当我调用zoomToRect:动画:时,委托(scrollViewDidScroll:和scrollViewDidZoom)只被调用一次,这会使我的子元素去同步,直到动画完成。事实上,子元素立即跳转,然后被缩放动画捕捉,直到一切都在正确的位置。这就好像动画没有在子视图CALayers上获得修改一样。
我试过用动画块手动动画,但情况相同,没有渐进的回调调用。我也尝试过KVO,但我不清楚如何使用UIScrollView管理的动画。
在iOS 4上有什么解决办法可以让我在UIScrollView缩放动画时将缩放值推送到我的子视图中?
发布于 2013-03-19 23:08:59
很残忍但很管用。
定义一些属性:
@property (nonatomic, strong) UIView *zoomedView;
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic) CGFloat currentScale;
通知UIScrollView
将放大哪个UIView
:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.zoomedView;
}
注册一个CADisplayLink
滴答。它也运行核心动画,因此它将被踢在相同的间隔:
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
查看缩放视图的presentationLayer
以获取当前值。
- (void)displayLinkTick
{
CALayer *zoomedLayer = self.zoomedView.layer.presentationLayer;
CGFloat scale = zoomedLayer.transform.m11;
if (scale != self.currentScale) {
self.currentScale = scale; // update property
// the scale has changed!
}
}
发布于 2011-09-26 10:50:59
在IOS 4.0中,动画是由操作系统完成的--我假设尽可能多地使用基于GPU的硬件加速。这样做的一个缺点是,很难将从另一个(动画)值派生出来的值动画化。与您的情况一样,子视图的位置取决于UIScrollView的缩放级别。为了实现这一点,您应该设置子视图的动画,使其与缩放的动画并行。试一试如下:
[UIView animateWithDuration:0.5 delay:0
options:UIViewAnimationOptionLayoutSubviews
animations:^{
theScrollView.zoomScale = zoomScale;
// layout the subviews here
} completion:^(BOOL finished) {}];
这应该从相同的动画上下文中设置子视图的框架属性,因此,它们应该由OS一起动画。
发布于 2010-11-15 20:15:29
在调用zoomScale
之后,为UIScrollView
的zoomToRect:animated:
属性的KVO注册。
[scrollView addObserver:self
forKeyPath:@"zoomScale"
options:(NSKeyValueObservingOptionNew |
NSKeyValueObservingOptionOld)
context:NULL];
然后,实现此方法:
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([keyPath isEqual:@"zoomScale"]) {
// use the new zoomScale value stored
// in the NSKeyValueChangeNewKey change
// dictionary key to resize your subviews
}
// be sure to call the super implementation
// if the superclass implements it
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
看看KVO 文档。
https://stackoverflow.com/questions/3993532
复制相似问题