首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在iOS 4.0中,为什么UIScrollView在动画时不触发scrollViewDidScroll或scrollViewDidZoom委托?

在iOS 4.0中,为什么UIScrollView在动画时不触发scrollViewDidScroll或scrollViewDidZoom委托?
EN

Stack Overflow用户
提问于 2010-10-22 02:47:14
回答 3查看 4.9K关注 0票数 29

我需要密切监视滚动视图的缩放,以便根据滚动视图的动画缩放更新内容视图的元素(管理多个CALayers的子视图)。

在iOS 3.1上,一切都按预期工作,我使用zoomToRect: UIScrollViewDelegate:和scrollViewDidScroll: message of UIScrollViewDelegate在动画进行时反复调用,允许我根据实际缩放更新子视图元素。

iOS 4.0上的相同代码不存在相同的行为。当我调用zoomToRect:动画:时,委托(scrollViewDidScroll:和scrollViewDidZoom)只被调用一次,这会使我的子元素去同步,直到动画完成。事实上,子元素立即跳转,然后被缩放动画捕捉,直到一切都在正确的位置。这就好像动画没有在子视图CALayers上获得修改一样。

我试过用动画块手动动画,但情况相同,没有渐进的回调调用。我也尝试过KVO,但我不清楚如何使用UIScrollView管理的动画。

在iOS 4上有什么解决办法可以让我在UIScrollView缩放动画时将缩放值推送到我的子视图中?

EN

回答 3

Stack Overflow用户

发布于 2013-03-19 23:08:59

很残忍但很管用。

定义一些属性:

代码语言:javascript
运行
复制
@property (nonatomic, strong) UIView *zoomedView;    
@property (nonatomic, strong) CADisplayLink *displayLink;
@property (nonatomic) CGFloat currentScale;

通知UIScrollView将放大哪个UIView

代码语言:javascript
运行
复制
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
     return self.zoomedView;
}

注册一个CADisplayLink滴答。它也运行核心动画,因此它将被踢在相同的间隔:

代码语言:javascript
运行
复制
self.displayLink  = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTick)];
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

查看缩放视图的presentationLayer以获取当前值。

代码语言:javascript
运行
复制
- (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!
    }
}
票数 10
EN

Stack Overflow用户

发布于 2011-09-26 10:50:59

在IOS 4.0中,动画是由操作系统完成的--我假设尽可能多地使用基于GPU的硬件加速。这样做的一个缺点是,很难将从另一个(动画)值派生出来的值动画化。与您的情况一样,子视图的位置取决于UIScrollView的缩放级别。为了实现这一点,您应该设置子视图的动画,使其与缩放的动画并行。试一试如下:

代码语言:javascript
运行
复制
[UIView animateWithDuration:0.5 delay:0
                    options:UIViewAnimationOptionLayoutSubviews
                 animations:^{
    theScrollView.zoomScale = zoomScale;
    // layout the subviews here
} completion:^(BOOL finished) {}];

这应该从相同的动画上下文中设置子视图的框架属性,因此,它们应该由OS一起动画。

也见这个问题的答案:如何使UIScrollView在动画期间发送scrollViewDidScroll消息

票数 1
EN

Stack Overflow用户

发布于 2010-11-15 20:15:29

在调用zoomScale之后,为UIScrollViewzoomToRect:animated:属性的KVO注册。

代码语言:javascript
运行
复制
[scrollView addObserver:self
            forKeyPath:@"zoomScale"
               options:(NSKeyValueObservingOptionNew |
                        NSKeyValueObservingOptionOld)
                context:NULL];

然后,实现此方法:

代码语言:javascript
运行
复制
- (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 文档

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3993532

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档