简体   繁体   English

动画 UIView 帧,子视图 UIScrollView 并不总是动画

[英]Animating a UIView frame, subview UIScrollView doesn't always animate

In this example.这个例子中。

I'm animating the PhotoViewerViewController's frame when I animate out the tabBarController (for fullscreen effect).当我为 tabBarController 设置动画时(用于全屏效果),我正在为 PhotoViewerViewController 的框架设置动画。 The PhotoViewer uses a uiscrollview to generate the same sort of effect Apple's photos app does. PhotoViewer 使用 uiscrollview 来生成与 Apple 的照片应用程序相同的效果。 For whatever reason sometimes it animates along with my PhotoViewer frame, and sometimes it doesn't.无论出于何种原因,它有时会与我的 PhotoViewer 框架一起制作动画,有时则不会。

You can see in the first example it jumps when increasing the frame size, but animates nicely when decreasing the frame size (and restoring the tab bar).您可以在第一个示例中看到它在增加帧大小时跳跃,但在减小帧大小(并恢复标签栏)时动画效果很好。

However in this example when the photo is vertical it jumps in both directions.然而在这个例子中,当照片是垂直的时,它会在两个方向上跳跃。

In both cases if I zoom in on the photo at all with the scrollview, it animates correctly in both directions.在这两种情况下,如果我使用滚动视图放大照片,它会在两个方向上正确动画。

I know the evidence is there, but I can't put my finger on what's happening here.我知道证据在那里,但我无法确定这里发生了什么。

Here's my animation block:这是我的 animation 块:

void (^updateProperties) (void) = ^ {
    self.navigationController.navigationBar.alpha = hidden ? 0.0f : 1.0f;
    self.navigationController.toolbar.alpha = hidden ? 0.0f : 1.0f;
    if (self.tabBarController) {

        int height = self.tabBarController.tabBar.bounds.size.height;
        for(UIView *view in self.tabBarController.view.subviews)
        {
            int newHeight;
            UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
            if (UIInterfaceOrientationIsPortrait(orientation)) {
                newHeight = hidden ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.height - height;
            } else {
                newHeight = hidden ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.width - height;
            }


            if([view isKindOfClass:[UITabBar class]])
            {
                [view setFrame:CGRectMake(view.frame.origin.x, newHeight, view.frame.size.width, view.frame.size.height)];
            } 
            else 
            {
                CGRect newFrame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, newHeight);
                [view setFrame:newFrame];

                // update our VC frame with animation
                [self.view setFrame:newFrame];

            }

        }
    }

};

Code adapted from a post on SO: UITabBar wont hide改编自 SO 上的帖子的代码: UITabBar wont hide

Full source on github . github上的完整源代码。

In general, if animations sometimes work and sometimes don't, it's because in the latter case a delayed perform is causing them to be effectively cancelled by setting the property concerned to its final value.一般来说,如果动画有时有效,有时无效,这是因为在后一种情况下,延迟执行会通过将相关属性设置为其最终值而导致它们被有效取消。

In the particular case of UIScrollView it often happens that -layoutSubviews is called without animation one run loop after your animation blocks have closed.UIScrollView的特定情况下,在 animation 块关闭后,经常会在没有 animation 一个运行循环的情况下调用-layoutSubviews For this reason I usually try to avoid doing any layout in that method where I have a UIScrollView in the view hierarchy (because particularly prior to iOS 5, UIScrollView is really trigger-happy on setting itself to need layout).出于这个原因,我通常会尽量避免在视图层次结构中有UIScrollView的方法中进行任何布局(因为特别是在 iOS 5、 UIScrollView之前需要布局)真的触发-happyZ。

I would recommend removing your call to -[EGOPhotoImageView layoutScrollViewAnimated:] from -layoutSubviews and add it to an overridden -setFrame: instead.我建议您从-layoutSubviews中删除对-[EGOPhotoImageView layoutScrollViewAnimated:]的调用,并将其添加到覆盖的-setFrame:中。

If you can target iOS4 and above, take a look at UIViewAnimationOptionLayoutSubviews too.如果您可以针对 iOS4 及更高版本,请查看UIViewAnimationOptionLayoutSubviews Using a block-based animation with this as an option might just work without changing anything else.使用基于块的 animation 作为选项,可能无需更改任何其他内容即可工作。

I tried your github code on iPad 4.2 and 4.3 simulators and it works fine... no image resizing whatsoever.我在 iPad 4.2 和 4.3 模拟器上尝试了您的 github 代码,它工作正常……没有任何图像大小调整。 There might be some version issues, Also: I tried changing your animations block and the following serves the same purpose:可能存在一些版本问题,另外:我尝试更改您的动画块,以下用于相同目的:

void (^updateProperties) (void) = ^ {
            self.navigationController.navigationBar.alpha = hidden ? 0.0f : 1.0f;
            self.navigationController.toolbar.alpha = hidden ? 0.0f : 1.0f; }

Let me know if I'm missing something:)如果我遗漏了什么,请告诉我:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM