【问题标题】:UIStackView - hide and collapse subview with animationUIStackView - 用动画隐藏和折叠子视图
【发布时间】:2019-05-31 23:26:59
【问题描述】:

我正在尝试像这样隐藏 UIStackView 的子视图:

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 2.0, 
      delay: 0, options: [.curveEaseOut], animations: {
    self.label.isHidden = true
    self.label.alpha = 0.0
    self.stackView.layoutIfNeeded()
})

但是,使用此代码后标签会立即消失。我怀疑这是因为将 isHidden 设置为 true,这是折叠所必需的。

有没有办法用动画隐藏和折叠 UIStackView 的 subvew?或者根本不使用 UIStackView 会更好?

【问题讨论】:

  • 是否可以修改子视图的高度?在动画块中,将高度和 alpha 设置为 0,完成后您可以在将 isHidden 设置为 true 的同时重置高度和 alpha
  • @Andrey 如果可能的话,请您向我们展示一下您的动画目前正在做什么?还有一件事,如果您要隐藏标签,那么为什么要设置 alpha?
  • 我还没有尝试过这个......解决方案就像在UIView.AnimationOptions的数组中添加键showHideTransitionViews一样简单......Apple docs状态“这个键导致视图隐藏或显示(而不是删除或添加)...”。
  • 我试过你的代码,发现标签慢慢塌陷,最后变得不可见。如果不是这样,你预计会有什么影响?

标签: ios swift uistackview


【解决方案1】:

根据Apple's documentation

您可以通过将这些更改放置在动画块中来对排列的子视图的 isHidden 属性和对堆栈视图的属性的更改进行动画处理。

我已经使用 iOS 12.1 模拟器测试了以下代码,它按预期工作。

UIView.animate(
    withDuration: 2.0,
    delay: 0.0,
    options: [.curveEaseOut],
    animations: {
        self.label.isHidden = true
        self.label.alpha = 0.0
})

【讨论】:

  • fwiw,也适用于堆栈视图之外的标签
【解决方案2】:

您可以为 alphacolor 等视图属性设置动画。但是,有些事情会立即发生 - 在这种情况下为 isHidden

这是一个使用UIView.animate的例子:

UIView.animate(withDuration: 2, delay: 0, options: .curveEaseOut, animations: {
    self.label.alpha = 0 // Changes the label's layer alpha value
}, completion: { finished in
    self.label.isHidden = true // Hides the label
    self.label.layer.alpha = 1 // Resets the label's alpha without un-hiding it
})

使用UIViewPropertyAnimator

UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 2, delay: 0, options: .curveEaseOut, animations: {
    self.label.alpha = 0 // Sets the label's alpha
}) { _ in
    self.label.isHidden = true // Hides the label
    self.label.alpha = 1 // Resets the label's alpha without un-hiding it
}

【讨论】:

  • 感谢您的回答,但在completion 块中设置isHidden 对我不起作用:正如我所说,我也想实现折叠动画。在这种情况下,子视图将在 alpha 动画为 0 后折叠而没有任何动画
【解决方案3】:

我已经尝试过您的代码。它的动画

if self.stackView.subviews.count > 0 {
            UIViewPropertyAnimator.runningPropertyAnimator(withDuration: 1.0, delay: 0, options: [.curveEaseOut], animations: {

                self.stackView.subviews[0].isHidden = true
                self.stackView.subviews[0].alpha = 0.0
                self.stackView.layoutIfNeeded()
            }) { (position) in
                self.stackView.subviews[0].removeFromSuperview()
            }
        }

【讨论】:

    【解决方案4】:

    只是你可以使用简单的解决方案和animateKeyframes 来淡化 alpha,然后隐藏,我认为这会给你你需要的东西所以在 1 秒和 0.8 秒褪色后隐藏

    // showLabel 是 Bool 来处理状态,在你的文件中声明它

    @IBAction func toggleStackLabelTapped(_ sender: UIButton) {
    
        showLabel = !showLabel
    
        UIView.animateKeyframes(withDuration: 1, delay: 0, options: .calculationModeLinear, animations: {
            UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.8) {
                self.label.alpha =  (self.showLabel) ? 1 : 0
            }
            UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 1) {
                self.label.isHidden = !self.showLabel
            }
    
        })
    }
    

    【讨论】:

      【解决方案5】:

      确保您没有对堆栈视图进行高度限制。 试试这个。

      UIView.animate(withDuration: 0.5) {
         self.stackView.subviews[INDEX_OF_LABEL_IN_STACK]?.alpha = 0
         self.stackView.subviews[INDEX_OF_LABEL_IN_STACK]?.isHidden = true
         self.view.layoutSubviews()
      }
      

      【讨论】:

      • 谢谢,但这种方法不会淡化子视图(不会改变它的 alpha)。它只会折叠子视图
      • 同理写 self.stackView.subviews[INDEX_OF_LABEL_IN_STACK]?.alpha = 0 你可以达到你想要的,如果你仍然没有达到你想要的,请与我分享stackview的截图跨度>
      • 这正是我正在尝试的,请参阅上面我的问题中的代码。该代码无法正常工作
      • 您不应直接致电layoutSubviews()。如果要强制更新布局,请在下一次绘图更新之前调用setNeedsLayout() 方法来执行此操作。如果您想立即更新视图的布局,请调用layoutIfNeeded() 方法。
      猜你喜欢
      • 2018-03-01
      • 2021-06-01
      • 2018-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多