简体   繁体   English

将自动布局与核心动画相结合

[英]Combining autolayout with core animation

I'm new to core animation and I'm struggling with one thing - how to combine autolayout with core animation. 我是核心动画的新手,我正在努力解决一件事 - 如何将autolayout与核心动画结合起来。 Actually I've found only one sentence in the documentation of Core Animation which refers to Autolayout here is it 实际上我在Core Animation的文档中只找到了一个句子,这里引用的是Autolayout

Remember to Update View Constraints as Part of Your Animation If you are using constraint-based layout rules to manage the position of your views, you must remove any constraints that might interfere with an animation as part of configuring that animation. 记住将视图约束更新为动画的一部分如果使用基于约束的布局规则来管理视图的位置,则必须删除可能会影响动画的任何约束,作为配置动画的一部分。 Constraints affect any changes you make to the position or size of a view. 约束会影响您对视图的位置或大小所做的任何更改。 They also affect the relationships between the view and its child views. 它们还会影响视图与其子视图之间的关系。 If you are animating changes to any of those items, you can remove the constraints, make the change, and then apply whatever new constraints are needed. 如果要为这些项中的任何项设置动画,则可以删除约束,进行更改,然后应用所需的任何新约束。

But as I've tried all is not as strait-forward as it may seem. 但是,正如我所做的那样,所有人并不像看起来那样直截了当。 Here is my scenario. 这是我的情景。

I've designed a sliding menu which uses autolayout extensively. 我设计了一个广泛使用自动布局的滑动菜单。 Here is the appearance of that view. 这是该视图的外观。 在此输入图像描述

I'm using autolayout constraints to force proportional positioning of those items in the sliding menu. 我正在使用自动布局约束来强制在滑动菜单中按比例定位这些项目。 Actually there are a lot of constraints there and I didn't want to post all of those in my question, and even may be they are not needed for direct answer of this question, however if you need them I can update the post with those constraints. 实际上有很多限制,我不想在我的问题中发布所有这些,甚至可能是他们不需要直接回答这个问题,但是如果你需要它们我可以用那些更新帖子限制。

The animation that you see in the gif was reached by only autolayout. 您在gif中看到的动画仅通过autolayout到达。 I just added outlet to the height constraint of the sliding menu and changed it in this way: (the code is written using Xamarin Monotouch, but I believe it should be clear what is done here for pure iOS developers) 我只是添加了插入滑动菜单的高度限制并以这种方式更改它:(代码是使用Xamarin Monotouch编写的,但我相信它应该很清楚这里为纯iOS开发人员做了什么)

private void AnimateSlideMenuAppearance()
    {
        float height;
        if (isSlideMenuShown) {
            height = 0;
        } else {
            height = slideMenuHeight;
        }
        UIView.Animate (0.4,
            delegate {
                this.slideMenuHeightConstraint.Constant = height;
                this.View.LayoutIfNeeded ();
            }, 
            delegate {
                isSlideMenuShown = !isSlideMenuShown;
            });
    }

Now I want to get more sophisticated appearance transition. 现在我希望获得更复杂的外观过渡。 CLICK HERE to see the effect that I want to reach. 点击这里查看我想要达到的效果。

Just to try out I tried to implement the disappearing part of that animation with series of CABasicAnimation s, but it was unsuccessful, I get strange behaviour. 只是为了尝试我尝试使用CABasicAnimation系列实现该动画的消失部分,但它不成功,我得到了奇怪的行为。

Can anybody suggest what I should do here? 任何人都可以建议我应该在这做什么吗? Is that possible to use autolayout to calculate the positions of the views, but somehow override the animation between autolayout size changes? 是否可以使用autolayout来计算视图的位置,但以某种方式覆盖自动布局大小更改之间的动画? I mean in my concrete example instead of proportionally decreasing the sizes of all buttons in menu I need to add FadeOut animation to them, animate the bounds to zero and also radically increase begin time of the animations from button to button in order to get the effect that I want. 我的意思是在我的具体例子中,而不是按比例减少菜单中所有按钮的大小,我需要向它们添加FadeOut动画,将边界设置为零动画,并从按钮到按钮从根本上增加动画的开始时间以获得效果我想要的。 Or may be I need to completely get rid of autolayout and manually calculate the sizes and animations? 或者我可能需要完全摆脱autolayout并手动计算大小和动画?

What is the best practice in these kind of scenarios - when you have complex autolayouting and you need custom Core Animation transitions between autolayout changes? 这种情况下的最佳做法是什么 - 当您有复杂的自动布局时,您需要在自动布局更改之间进行自定义核心动画转换? I hope that I described the question well. 我希望我能很好地描述这个问题。 Thank you for your answers. 谢谢您的回答。

This is completely feasible, while it may be complex solely because it looks like your desired cases will have multiple animations. 这是完全可行的,虽然它可能很复杂,因为它看起来像你想要的案例将有多个动画。

However, I noticed one thing in your code that's odd: you change the constant on the constraint ( this.slideMenuHeightConstraint.Constant = height ) in the animation block, instead of before it. 但是,我注意到你的代码中有一件事是奇怪的:你动画块中改变约束( this.slideMenuHeightConstraint.Constant = height )的常量,而不是在它之前。 For nearly all cases I can imagine, you should change the constraint before the animation block. 对于我能想象的几乎所有情况,你应该在动画块之前改变约束。 Constraints are not visually rendered until either the next UI run loop (or by setNeedsUpdateConstraints to force it for the next run loop), or immediately by layoutIfNeeded . 在下一个UI运行循环(或通过setNeedsUpdateConstraints强制它用于下一个运行循环)之前,或者通过layoutIfNeeded立即呈现约束。 And since [UIView animate:...] is doing this for you, layoutIfNeeded should (generally) be the only thing in your animate block, when animating autolayout. 因为[UIView animate:...]正在为你做这个,所以在动画自动布局时, layoutIfNeeded应该(通常)是动画块中的唯一内容。

In your case, you will have to make the animation somewhat reactive, however - for eg, if you want to add those buttons in like in the example and have them pop in, animate out, and grow. 在你的情况下,你将不得不使动画有点反应 - 例如,如果你想在示例中添加这些按钮并让它们弹出,动画,并增长。 After calling layoutIfNeeded , you can safely check the frame size. 调用layoutIfNeeded ,您可以安全地检查帧大小。 If it's beyond your threshold (or some other metric), you can trigger then animations of the buttons. 如果它超出了您的阈值(或其他某个指标),您可以触发按钮的动画。 (So yes, this may be a case where I'd add more code inside the animate block -- check the threshold, begin other animation, etc). (所以是的,这可能是我在动画块中添加更多代码的情况 - 检查阈值,开始其他动画等)。

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

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