使用 isHidden 的 UIStackView 动画

Posted

技术标签:

【中文标题】使用 isHidden 的 UIStackView 动画【英文标题】:Animation of UIStackView using isHidden 【发布时间】:2018-08-10 14:06:03 【问题描述】:

[编辑] 我已经推送了一个包含零高度约束解决方案的提交,但是,现在我必须处理隐式 UISV 约束。

我花了几个小时来了解如何更改堆栈视图中出现/消失的项目的动画。 我想从屏幕底部动画显示这两个按钮,但是,它们总是从右上角飞出:

有没有 Cocoa 的方式来配置动画从底部开始? 附言Link to the project.

动画块:

UIView.animate(withDuration: 5.0,
                   delay: 0.5,
                   options: .curveEaseInOut,
                   animations:
        
            self.buttons.forEach  $0.isHidden = !$0.isHidden 
            self.stack.layoutIfNeeded()
        , completion: nil)

【问题讨论】:

你能只显示你的动画块吗? 您链接的项目没有任何堆栈视图或动画代码。 我不认为 stackviews 是为这种动画设计的。为什么首先要为此使用堆栈视图? @Abizern 已上传 @RakeshaShastri,因为它比普通的 UIView 布局更简单。 【参考方案1】:

这里有两种方法可以让按钮看起来像是从屏幕底部向上滑动。这两种方法都不会涉及更改堆栈视图的高度或按钮的isHidden

解决方案 1

如果视图控制器视图(场景的“根视图”)的底部边缘位于屏幕底部边缘,或者启用了“剪辑到边界”,则此解决方案效果很好。

将堆栈视图的底部限制在根视图安全区域的底部,优先级为 999。 将堆栈视图的顶部约束到根视图的底部(不是安全区域),优先级为 1000,但通过在其属性检查器中取消选中“已安装”来使此约束无效。将名为 stackHidingConstraint 的插座连接到此约束。

要切换按钮的可见性,请设置stackHidingConstraint.isActive = !stackHidingConstraint.isActive。当约束处于活动状态时,它通过将堆栈视图放在根视图的底部边缘来隐藏按钮。当约束处于非活动状态时,priority-999 底部边缘约束通过将堆栈视图置于根视图安全区域的底部边缘上方来显示按钮。

看起来像这样:

解决方案 2

此解决方案适用于解决方案 1 不适用的情况(如果场景的根视图的底部边缘不在屏幕底部边缘并且未启用“剪辑到边界”),但需要视图层次结构的微小变化。

将堆栈视图嵌入容器UIView。我们称之为堆栈隐藏视图。 为堆栈隐藏视图打开“Clip to Bounds”。 将堆栈隐藏视图的左侧、右侧和底部边缘约束到根视图安全区域的左侧、右侧和底部边缘。 将堆栈视图的左侧、右侧和顶部边缘约束到堆栈隐藏视图的左侧、右侧和顶部边缘。 将堆栈视图的底部边缘限制为堆栈隐藏视图的底部边缘优先级为 999。 将堆栈隐藏视图的高度限制为 0。将名为 stackHidingConstraint 的插座连接到此限制。在情节提要中使此约束处于非活动状态(卸载)。

再一次,要切换按钮的可见性,请设置stackHidingConstraint.isActive = !stackHidingConstraint.isActive。当约束处于活动状态时,它通过将堆栈隐藏视图的高度设置为零来隐藏按钮。由于堆栈隐藏视图剪辑了它的子视图,这使得子视图不可见。当约束处于非活动状态时,priority-999 底部边缘约束使堆栈隐藏视图的高度与堆栈视图相等,因此子视图可见。

看起来像这样:

与解决方案 1 的唯一明显区别是,在解决方案 1 中,您可以看到按钮在标签栏下方滑动。在解决方案 2 中,它们不会在标签栏下方滑动。

你可以在这里找到我的测试项目:https://github.com/mayoff/StackViewAnimation

【讨论】:

拍手 拍手努力!在我看来,您应该会看到按钮从栏下方滑动。【参考方案2】:

我已经使用高度约束的动画修复了它。似乎这是实现行为的唯一方法。

【讨论】:

那是错误的。你应该从下往上为一个完整的按钮设置动画。不为高度设置动画。用户知道区别。请看一下 Rob 的回答。

以上是关于使用 isHidden 的 UIStackView 动画的主要内容,如果未能解决你的问题,请参考以下文章

应用程序崩溃isHidden属性

应用程序在 isHidden 属性上崩溃

即使在使用 view.setNeedsDisplay() 刷新视图后,.isHidden 属性也不反映对视图的更改

更改集合视图的 isHidden 属性不适用于搜索栏取消按钮

为啥 Files.isHidden(Path) 为 Windows 上的目录返回 false?

即使在使用view.setNeedsDisplay()刷新视图后,.isHidden属性也不会反映视图的更改