【问题标题】:Animating UIStackView Subviews glitches to top left动画 UIStackView 子视图在左上角出现故障
【发布时间】:2021-06-01 01:51:54
【问题描述】:

我正在尝试为 stackview 的子视图(它们是包含另一个 stackview 的 UIView)设置动画,当它们进入和离开时:

UIView.animate(withDuration: 2, delay: 0, options: .curveLinear) {
    self.stackView.addArrangedSubview(someChildView) // same behaviour when hiding
    self.stackView.layoutIfNeeded()
    self.contentView.layoutIfNeeded()
    self.scrollView.layoutIfNeeded()
    self.view.layoutIfNeeded()
}

我遇到的问题是它总是从屏幕左上角进入然后增长。

我似乎无法弄清楚为什么它不能正确设置动画(它完全忽略了动画选项,它总是像 GIF 一样来自左上角)。

这是视图的设置方式:

scrollView = {
    let scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    return scrollView
}()

stackView = {
    let stackView = UIStackView()
    stackView.axis = .vertical
    stackView.distribution = .fill
    stackView.translatesAutoresizingMaskIntoConstraints = false
    
    return stackView
}()

contentView = {
    let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    return view
}()

contentView.addSubview(stackView)
scrollView.addSubview(contentView)
view.addSubview(scrollView)

scrollView.showsVerticalScrollIndicator = false
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true

contentView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
contentView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
contentView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
contentView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
contentView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

stackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 20).isActive = true
stackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20).isActive = true
stackView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20).isActive = true
stackView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -50).isActive = true

问题:似乎子视图在动画开始时不知道它们的宽度,并且只在它期间计算出来(?)。如何正确设置动画?

【问题讨论】:

  • 您并没有真正调用动画块中的动画属性,可能动画是堆栈视图的框架随着新视图的添加而发生变化(从 x/y 点为 0 开始)。如果您只想优雅地显示新视图,则首先将视图添加到高度为零的堆栈视图中,然后在动画块中,将框架扩展为所需的任何大小,并可能添加从 0 到的 alpha 更改1 如果你喜欢这种淡化的外观。
  • @SuperTully 你说得对,我将动画块更改为动画isHidden = falsealpha = 1。但是,来自左上角的元素的问题仍然存在。

标签: ios swift uiview uiviewanimation


【解决方案1】:

最终起作用的似乎是来自屏幕左上角的元素的解决方案是调用view.layoutIfNeeded()

viewToAdd.alpha = 0
viewToAdd.isHidden = true
self.stackView.addArrangedSubview(viewToAdd)
self.view.layoutIfNeeded() // view is the very root view

UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 5, options: .curveEaseInOut) {
    viewToAdd.isHidden = false
    viewToAdd.alpha = 1
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2022-12-04
    • 1970-01-01
    • 2014-09-09
    • 2019-09-22
    • 2015-01-23
    • 2021-06-28
    相关资源
    最近更新 更多