取出后如何将uiview放回stackview?

How to put a uiview back in a stackview after I took it out?

我有一个 viewcontroller 包含多个堆栈视图。有一个按钮,当按下时,相应的 uiview 将在原始视图内变为全屏。有一个不同的按钮应该使 uiview 返回到其原始堆栈视图。 uiview 本身包含其他视图。我在这样做时遇到了一些问题。 uiview 最终出现在 stackview 中,但与以前的 size/place 大不相同。我不确定如何解决这个问题,现在已经研究了几个小时,查看了多个来源。

这是使 uiview 全屏显示的代码:

private func moveToFrontOfCardView(v: UIView) {
    originalView = v.superview

    if let stack = originalView as? UIStackView {
        stack.removeArrangedSubview(v)
    }
    myCardView.addSubview(v)

    let topConstraint = NSLayoutConstraint(item: v, attribute: .top, relatedBy: .equal, toItem: myCardView, attribute: .top, multiplier: 1, constant: 10)
    let bottomConstraint = NSLayoutConstraint(item: v, attribute: .bottom, relatedBy: .equal, toItem: myCardView, attribute: .bottom, multiplier: 1, constant: -10)
    let leftConstraint = NSLayoutConstraint(item: v, attribute: .left, relatedBy: .equal, toItem: myCardView, attribute: .left, multiplier: 1, constant: 10)
    let rightConstraint = NSLayoutConstraint(item: v, attribute: .right, relatedBy: .equal, toItem: myCardView, attribute: .right, multiplier: 1, constant: -10)

    myCardView.addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint])
}

这是我希望它返回时使用的代码:

private func moveToOriginalPosition(v: UIView) {
    if let stack = originalView as? UIStackView {
        stack.addArrangedSubview(v)
    }
}

有人知道我该如何解决这个问题吗?

编辑 我试过 Saqib 和 Billals 的回答,但我得到的结果是:

声明一个 class 变量用于跟踪视图的索引

var selectedIndex = 0 // Contains Current Seleceted view's index

overrie func viewDidLoad() { ...
  • 在从堆栈视图中删除视图之前,像这样获取视图索引selectedIndex = stack.subviews.index(of: v)

  • 保留对所有约束的引用。

  • 在添加回来之前禁用所有约束topConstraint.isActive = false

  • 现在使用 stack.insertArrangedSubview(view, at: selectedIndex)

  • 在同一索引处添加视图

另一种选择是创建一个相同的新视图,并且只是 hide/unhide stackview 中的视图。 StackView 会自动为隐藏视图相应地填充 space。

从外观上看,您不需要删除原始视图。您可以制作它的副本,然后全屏显示副本。然后,当您关闭此副本时,您将释放对它的引用

当您想要再次将视图添加到 stackView 时,您应该取消激活从 stackView 中删除时添加到视图的约束。 为此,您应该创建 viewController class 的约束实例,然后,像这样编写 moveToOriginalPosition(v: UIView) 方法:

    private func moveToOriginalPosition(v: UIView) {
        if let stack = originalView as? UIStackView {
        stack.addArrangedSubview(v)
        topConstraint.isActive = false
        bottomConstraint.isActive = false
        leftConstraint.isActive = false
        rightConstraint.isActive = false

        }
   }

当然,您应该从 moveToFrontOfCardView(v: UIView) 方法中删除这些代码行:

    self.topConstraint = NSLayoutConstraint(item: v, attribute: .top, relatedBy: .equal, toItem: myCardView, attribute: .top, multiplier: 1, constant: 10)
    self.bottomConstraint = NSLayoutConstraint(item: v, attribute: .bottom, relatedBy: .equal, toItem: myCardView, attribute: .bottom, multiplier: 1, constant: -10)
    self.leftConstraint = NSLayoutConstraint(item: v, attribute: .left, relatedBy: .equal, toItem: myCardView, attribute: .left, multiplier: 1, constant: 10)
    self.rightConstraint = NSLayoutConstraint(item: v, attribute: .right, relatedBy: .equal, toItem: myCardView, attribute: .right, multiplier: 1, constant: -10)

    myCardView.addConstraints([topConstraint, bottomConstraint, leftConstraint, rightConstraint])

并将它们添加到您初始化视图的位置。并在 moveToFrontOfCardView(v: UIView) 方法中用上面的行替换下面的行:

        topConstraint.isActive = true
        bottomConstraint.isActive = true
        leftConstraint.isActive = true
        rightConstraint.isActive = true