【问题标题】:StackView isHidden attribute not updating as expectedStackView isHidden 属性未按预期更新
【发布时间】:2017-10-05 12:20:52
【问题描述】:

如果UITextField 的值等于"Other",我正在尝试更新UIStackView 以便显示一个字段。这是我的代码:

@IBOutlet var stackView: UIStackView!
func updateView() {
    print("UPDATING")
    UIView.animate(withDuration: 0.25, animations: { () -> Void in
         if(self.myTextField.text! == "Other") {
              print("SHOWING")
              self.stackView.arrangedSubviews[3].isHidden = false
         } else {
              print("HIDING")
              self.stackView.arrangedSubviews[3].isHidden = true
         }
         print("Is hidden: \(self.stackView.arrangedSubviews[3].isHidden )")
    })

示例输出如下所示:

> UPDATING
> HIDING
> Is hidden: true
> UPDATING
> SHOWING
> Is hidden: true

如您所见,isHidden 属性报告为true,无论上面的代码将其设置为什么。我真的不知道为什么会这样,但也许这里有人可以?有什么明显的检查吗? isHidden有什么不能更新的原因吗? (注意输出中没有出现错误)。

【问题讨论】:

  • 如果我从字面上获取您的代码示例和您的描述,由于区分大小写,它不起作用 - “其他”(如您的描述)与“其他”(如示例)。您可能想考虑这个:self.myTextField.text!.lowercaseString == "other".
  • 抱歉,这只是一个糟糕的描述,我会更新 - 请查看输出以获取证据
  • @Ben 你明白了吗? zisoft 的解决方案去掉了动画,所以对我不好。如果我删除动画块,一切都会按预期进行。
  • @Levi 我相信 zisoft 的回答确实允许动画(它似乎确实在查看代码),但是我实际上目前没有工作副本来证明这一点 - 抱歉!跨度>
  • 没问题,我使用了一种解决方法,我在动画的完成块中将项目设置为显示/隐藏,而不仅仅是在动画块中我不喜欢这个解决方案,但它已修复错误

标签: ios swift uistackview


【解决方案1】:

已知 UIStackView 错误 (http://www.openradar.me/25087688)。关于它有一个线程:(Swift: Disappearing views from a stackView)。长话短说:

错误是在堆栈视图中隐藏和显示视图是 累积。奇怪的苹果错误。如果您在堆栈视图中隐藏一个视图两次, 您需要显示两次才能将其取回。

要解决此问题,您可以使用以下扩展:

extension UIView {
    var isHiddenInStackView: Bool {
        get {
            return isHidden
        }
        set {
            if isHidden != newValue {
                isHidden = newValue
            }
        }
    }
}

【讨论】:

  • 这是我隐藏元素两次的问题非常感谢!
  • 我在 iOS 13 中仍然看到这个问题。我在 UITableViewCell 的 StackView 中有两个标签,其中一个或两个标签应该被隐藏。有时标签是可见的,即使它们被标记为隐藏。我只能通过在情节提要中将标签设置为 Hidden true 然后使用 isHiddednInStackView 来更新它们的可见性来修复它。如果他们开始 isHidden false 然后将 isHidden 设置为 true 他们有时仍然可见。旋转 iPad 可以使某些行中的标签变得可见。
【解决方案2】:

用户界面的更新总是必须在主线程(法律)上完成。

所以在主标题上包装你的 UI 更新:

@IBOutlet var stackView: UIStackView!
func updateView() {
    print("UPDATING")
    UIView.animate(withDuration: 0.25, animations: { () -> Void in
        DispatchQueue.main.async {  // UI updates on the main thread
            if(self.myTextField.text! == "Other") {
                print("SHOWING")
                self.stackView.arrangedSubviews[3].isHidden = false
             } else {
                print("HIDING")
                self.stackView.arrangedSubviews[3].isHidden = true
             }
             print("Is hidden: \(self.stackView.arrangedSubviews[3].isHidden )")
        }
    })

【讨论】:

  • 完美运行,谢谢!你知道为什么 UIView.animate 默认不在主线程上完成吗?不然怎么用呢?
  • 很高兴为您提供帮助。请将答案标记为已接受。动画正在另一个线程上运行,以防止主线程被阻塞。
  • 在计时器到期之前我不能,但我当然会这样做。我认为这是有道理的——所以除了主线程之外,你不能在任何东西上更改 isHidden 属性,但是一旦更改了这些属性,动画就可以摆脱它。再次感谢!
  • 我认为这不是正确的解决方案,动画的持续时间在异步上被忽略了。如果你把你的 0.25 秒换成 3 秒,你会发现它不起作用。
  • 不应该被接受:)
【解决方案3】:

尝试将 alpha 与 isHidden 属性一起操作:

self.stackView.arrangedSubviews[3].isHidden = true
self.stackView.arrangedSubviews[3].alpha = 0

self.stackView.arrangedSubviews[3].isHidden = false
self.stackView.arrangedSubviews[3].alpha = 1

【讨论】:

    猜你喜欢
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2021-11-22
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多