Swift:从stackView中消失的视图

Ben*_*Ben 12 iphone ios swift uistackview

我的主要故事板中有一个相当简单的设置:

  • 包含三个视图的堆栈视图
  • 第一个视图具有固定高度并包含段控制器
  • 另外两个视图没有限制,这个想法是一次只有一个是活动的,从而填补了可用的空间

我有代码将处理更改视图活动视图,如下所示:

import Foundation
import UIKit
class ViewController : UIViewController {
    @IBOutlet weak var stackView: UIStackView!
    @IBOutlet weak var segmentController: UISegmentedControl!
    @IBAction func SegmentClicked(_ sender: AnyObject) {
        updateView(segment: sender.titleForSegment(at: sender.selectedSegmentIndex)!)
    }
    override func viewDidLoad() {
        updateView(segment: "First")
    }
    func updateView(segment: String) {
        UIView.animate(withDuration: 1) {
            if(segment == "First") {
                self.stackView.arrangedSubviews[1].isHidden = false
                self.stackView.arrangedSubviews[2].isHidden = true
            } else {
                self.stackView.arrangedSubviews[1].isHidden = true
                self.stackView.arrangedSubviews[2].isHidden = false

            }
            print("Updating views")
            print("View 1 is \(self.stackView.arrangedSubviews[1].isHidden ? "hidden" : "visible")")
            print("View 2 is \(self.stackView.arrangedSubviews[2].isHidden ? "hidden" : "visible")")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,当选择名为"First"的选项卡时,索引1处的子视图应显示,而隐藏2,当选择任何其他内容时,索引2处的子视图应显示,而隐藏1.

这似乎首先起作用,如果我慢慢改变视图,但如果我更快一点,索引1处的视图似乎在几次单击后保持永久隐藏,导致索引0处的视图覆盖整个屏幕.我已经放置了一个显示问题的动画和下面故事板的截图.输出显示问题发生时,单击第一个段时两个视图都保持隐藏状态.

任何人都可以告诉我为什么会这样吗?这是一个错误,还是我不做我应该做的事情?

提前谢谢了!

动画显示问题

堆视图的图象在故事画板的

更新:我似乎能够通过按顺序转到First> Second> Third> Second> First段来可靠地重现问题.

Dav*_*ton 44

错误是在堆栈视图中隐藏和显示视图是累积的.奇怪的苹果虫.如果在堆栈视图中隐藏视图两次,则需要显示两次才能将其恢复.如果你显示三次,你需要隐藏它三次以实际隐藏它(假设它被隐藏起来).

这与使用动画无关.

因此,如果您在代码中执行此类操作,仅隐藏视图(如果它可见),您将避免此问题:

if myView.isHidden == false {
    myView.isHidden = true
}
Run Code Online (Sandbox Code Playgroud)

  • 没错,任何地方都没有记录。调试为什么我的视图未显示在stackview中使我发了疯。言语无法说明这种实现有多么愚蠢!非常感谢,戴夫! (2认同)
  • 你先生是上帝. (2认同)

San*_*man 9

在Dave Batton的回答很好的基础上,您还可以添加UIView扩展,使呼叫站点更加干净,IMO。

extension UIView {

    var isHiddenInStackView: Bool {
        get {
            return isHidden
        }
        set {
            if isHidden != newValue {
                isHidden = newValue
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后stackView.subviews[someIndex].isHiddenInStackView = false,如果您要在堆栈视图中管理多个视图而不是一堆if语句,则可以调用。


Ben*_*Ben 5

最后,在尝试了这里的所有建议之后,我仍然无法弄清楚为什么会出现这样的情况,所以我联系了苹果公司,要求我提交错误报告。不过,我确实找到了解决方法,首先取消隐藏两个视图,这解决了我的问题:

func updateView(segment: String) {
    UIView.animate(withDuration: 1) {
        self.stackView.arrangedSubviews[1].isHidden = false
        self.stackView.arrangedSubviews[2].isHidden = false
        if(segment == "First") {
            self.stackView.arrangedSubviews[2].isHidden = true
        } else {
            self.stackView.arrangedSubviews[1].isHidden = true
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我在 UITableViewCell 中的 UIStackView 上遇到了同样的问题。由于单元格会被重用,因此当您快速滚动表格时,堆栈视图可能会快速连续地隐藏/取消隐藏组件。我的解决方案是在 UITableViewCell 的“prepareForReuse”方法中取消隐藏,然后仅在必要时隐藏。这似乎有效。可能会帮助其他人:) (5认同)