简体   繁体   English

作为容器视图一部分的按钮图像出现在该视图应该动画之前

[英]Button images which are part of a Container View appear before that view is supposed to animate in

I've implemented a custom dialog box in a game (showing options when the game is paused) by using a Container View in the main game's ViewController.我通过在主游戏的 ViewController 中使用Container View在游戏中实现了一个自定义对话框(在游戏暂停时显示选项)。 That Container View has a constraint to be centered vertically and I'm using that constraint to animate this custom dialog box.该容器视图有一个垂直居中的约束,我正在使用该约束来为这个自定义对话框设置动画。

The dialog box itself is an image of a wooden board on a pole with 4 buttons, each being an image I prepared.对话框本身是一个带有 4 个按钮的杆子上的木板图像,每个按钮都是我准备的图像。 These buttons are arranged in a vertical Stack View which contains 2 horizontal Stack Views, each with 2 buttons, so they will be laid out nicely symmetrical.这些按钮排列在一个垂直的 Stack View 中,其中包含 2 个水平的 Stack View,每个都有 2 个按钮,因此它们的布局非常对称。

All of the above is done in Interface Builder.以上所有都是在 Interface Builder 中完成的。 So a segue was automatically added from the game's main ViewController to the new Pause Dialog View Controller.因此,从游戏的主 ViewController 自动添加了一个 segue 到新的暂停对话框视图 Controller。

In my game's main ViewController I move the Container View out of view by adding the following to my viewDidLoad(): dialogBoxYConstraint.constant -= (view.bounds.height)在我的游戏的主 ViewController 中,我通过将以下内容添加到我的 viewDidLoad() 将容器视图移出视图: dialogBoxYConstraint.constant -= (view.bounds.height)

Then when the user clicks on a PAUSE button which should show this dialog, the following code is running:然后,当用户单击应显示此对话框的暂停按钮时,将运行以下代码:

         
        UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut) {

            self.dialogBoxYConstraint.constant += (self.view.bounds.height)
            self.view.layoutIfNeeded()
        }
    }

So this code will bring the constraint's constant back to its original location and it will show the dialog box that I put inside the Container View.所以这段代码会将约束的常量带回到它的原始位置,它会显示我放在容器视图中的对话框。

When the user clicks on the PAUSE button all of this indeed happens and there's a nice animation with the wooden board and all 4 buttons fall into place and all buttons are clickable.当用户点击 PAUSE 按钮时,所有这一切确实发生了,并且有一个漂亮的 animation 和木板,所有 4 个按钮都到位并且所有按钮都是可点击的。 Here's an image (disregard the small white buttons, these are temporary work-in-progress):这是一张图片(忽略白色的小按钮,这些是临时进行中的工作):

在此处输入图像描述

But , before that, before I click on the PAUSE button, I always see part of the buttons all the way on top.但是,在那之前,在我点击暂停按钮之前,我总是看到部分按钮一直在顶部。 I see the lower 2 buttons completely and a bit of those above as in the following image:我完全看到下面的 2 个按钮和上面的一些按钮,如下图所示:

在此处输入图像描述

As you can see, the wooden board isn't here, only the buttons, and when I do press the PAUSE button everything together correctly animates to the right place as in the 1st image.正如您所看到的,木板不在这里,只有按钮,当我按下暂停按钮时,所有东西都正确地动画到正确的位置,如第一张图片所示。

(It's an AR app so you basically see my walls in the background, but that's irrelevant for this question). (这是一个 AR 应用程序,所以你基本上可以在背景中看到我的墙,但这与这个问题无关)。

Moreover, when the buttons are on top, they are not clickable.此外,当按钮在顶部时,它们是不可点击的。
Also, it doesn't matter if I change the constraint's constant to be even higher, say I do this:此外,如果我将约束的常量更改为更高也没关系,比如我这样做:
dialogBoxYConstraint.constant -= (view.bounds.height + 500)
the buttons will always show at the same place.按钮将始终显示在同一位置。
And if I try to put this line in viewDidAppear then I can see the whole board with the buttons as in the first image for a second on a black background and then I get what you see in the 2nd image, which makes sense.如果我尝试将此行放在viewDidAppear中,那么我可以在黑色背景上看到第一张图片中带有按钮的整个面板一秒钟,然后我得到你在第二张图片中看到的内容,这是有道理的。

The above happens whether or not I've implemented the prepare(for segue: ) The segue itself is actually happening immediately as the main view is loaded, which is why I had to initially move it out of view.无论我是否实施了prepare(for segue: ) :) 都会发生上述情况 segue 本身实际上是在加载主视图时立即发生的,这就是为什么我不得不最初将它移出视图。

As a test, I tried to set one button's isHidden to true in the Pause Dialog View Controller and then set it to false in the prepare(for segue: ) , thinking that maybe that would do something, but the button remained hidden all the time.作为测试,我尝试在暂停对话框视图 Controller 中将一个按钮的isHidden设置为 true,然后在prepare(for segue: ) :) 中将其设置为 false,认为这可能会有所作为,但该按钮一直处于隐藏状态.
(Side question: how should I perform such changes in this child View Controller only after the user presses the PAUSE button? Since the segue happens already from the start, I don't understand how to control such changes only later on by user action?) (附带问题:只有在用户按下 PAUSE 按钮后,我应该如何在这个子视图 Controller 中执行此类更改?由于 segue 从一开始就发生了,我不明白如何通过用户操作控制此类更改? )

I'm not sure what I'm doing wrong.我不确定我做错了什么。 Looks like a glitch, but, as always, I guess it's something I did.看起来像个小故障,但一如既往,我想这是我做的。 I had assumed that moving the view's constraint should always move all of its contents together.我曾假设移动视图的约束应该始终将其所有内容一起移动。
Anyone has any idea why the buttons are always there at the top?任何人都知道为什么按钮总是在顶部?

I saw that there is a present(_:animated:completion:) method to present VC's.我看到有一个present(_:animated:completion:)方法来呈现 VC。 Should I be looking into this instead of animating the constraint as I did???我应该研究这个而不是像我那样对约束进行动画处理吗???

Posting this as an answer, as per the OP's comments...根据 OP 的评论,将此作为答案发布......

It can be very difficult to debug layouts when UI element are "clear."当 UI 元素“清晰”时,调试布局可能会非常困难。 Giving them background colors allows you to easily see the framing at run-time.给他们背景 colors 可以让您在运行时轻松查看框架。

Also, Debug View Hierarchy can be very helpful, because you can inspect constraints (and even see hidden or out-of-bounds elements).此外, Debug View Hierarchy可能非常有用,因为您可以检查约束(甚至可以查看隐藏的或越界的元素)。 Note that you may need to temporarily disable certain features - such as playing video or an active AR scene.请注意,您可能需要暂时禁用某些功能 - 例如播放视频或活动的 AR 场景。

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

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