【问题标题】:IOS how to completely remove a ViewIOS如何彻底删除一个View
【发布时间】:2018-10-23 19:21:45
【问题描述】:

我想完全隐藏一个视图。我是ios新手。但我在android方面有很好的工作经验。

所以在 android 中我们可以将可见性设置为消失。它完全从布局中删除了视图。我想在IOS中做同样的事情。这是布局/设计示例

查看 1 视图2(这是我要隐藏和显示的) 查看 3

现在,当我想隐藏视图 2 时,我希望视图 2 的空间也从屏幕上消失,并且视图 1 和视图 3 必须粘在一起。当视图 2 设置为可见时,它必须按顺序显示。即查看 1,2,3

现在我正在做的是设置 view2.ishidden = true 但它没有按我想要的方式工作。

请告诉我 IOS 中 android 的 view.gone 是什么等价物。 ???

【问题讨论】:

  • 使用这个view2.removeFromSuperview()
  • 那么如何将它添加回同一个地方?
  • 添加视图使用 -> view.addSubview(view2) 和 view2.frame = ... 并删除 view2.removeFromSuperview()
  • 如果你想删除然后再添加,这是 isHidden 属性的目的
  • 有一个名为“UIStackView”的组件,它是您可以在android中获得view.gone功能的组件。当你在 stackview 中放置 3-4 个视图并将其中一个隐藏时,其余的会正确布局。

标签: ios iphone


【解决方案1】:

有几种方法可以实现这一点,但您在这里缺少的是有关如何设置布局的一些关键信息。

我会假设您拥有的 3 个视图是垂直对齐的,彼此相邻且宽度相等。

以编程方式,我们从水平角度看到的内容已完成:

let firstLeading = NSLayoutConstraint(item: view1, attribute: .leading, relatedBy: .equal, toItem: parent, attribute: .leading, multiplier: 1.0, constant: 0.0)
let betweenSecondAndFirst = NSLayoutConstraint(item: view2, attribute: .leading, relatedBy: .equal, toItem: view1, attribute: .trailing, multiplier: 1.0, constant: 0.0)
let secondEqualWidth = NSLayoutConstraint(item: view2, attribute: .width, relatedBy: .equal, toItem: view1, attribute: .width, multiplier: 1.0, constant: 0.0)
let betweenThirdAndSecond = NSLayoutConstraint(item: view3, attribute: .leading, relatedBy: .equal, toItem: view2, attribute: .trailing, multiplier: 1.0, constant: 0.0)
let lastEqualWidth = NSLayoutConstraint(item: view3, attribute: .width, relatedBy: .equal, toItem: view1, attribute: .width, multiplier: 1.0, constant: 0.0) // Note to view1 to make things easier
let lastTrailing = NSLayoutConstraint(item: view3, attribute: .trailing, relatedBy: .equal, toItem: parent, attribute: .trailing, multiplier: 1.0, constant: 0.0)

当第二个被跳过时,我们可以简单地禁用betweenThirdAndSecond 并将betweenThirdAndFirst 添加为:

let betweenThirdAndFirst = NSLayoutConstraint(item: view3, attribute: .leading, relatedBy: .equal, toItem: view1, attribute: .trailing, multiplier: 1.0, constant: 0.0)

您可以使用约束上的属性来启用或禁用它们。或者您可以简单地使用优先级并将它们从 900 切换到 100。您实际上可以在情节提要中设置所有这些约束,然后将 2 作为插座拖到您的代码中。然后只需:

func setMiddleViewShown(_ shown: Bool) {
    UIView.animate(withDuration: 0.3) {
        self.betweenThirdAndSecond.priority = UILayoutPriority(rawValue: shown ? 900.0 : 100.0)
        self.betweenThirdAndFirst.priority = UILayoutPriority(rawValue: shown ? 100.0 : 900.0)
        self.view2.alpha = shown ? 1.0 : 0.0
        parent.layoutIfNeeded() // parent is most likely "self.view"
    }
}

这种方式可能是您可以控制的最佳方式(主要是动画)。但是您也可以使用UIStackView,它具有插入或删除视图的方法。 UICollectionView 也应该可以工作。或者您知道.. 只需以编程方式完成所有操作,忽略约束,只需为每个视图设置 frame。

在使用UIStackView 时,我能想到的最低要求如下:

class ViewController: UIViewController {

    let views: [UIView] = [
    { let view = UIView(); view.backgroundColor = .red; return view; }(),
    { let view = UIView(); view.backgroundColor = .green; return view; }(),
    { let view = UIView(); view.backgroundColor = .blue; return view; }()
    ]

    lazy var stackView: UIStackView = {
        let stackView = UIStackView(frame: CGRect(x: 50.0, y: 100.0, width: 300.0, height: 200.0))
        self.view.addSubview(stackView)
        stackView.backgroundColor = .black
        stackView.distribution = .fillEqually
        return stackView
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        stackView.addArrangedSubview(views[0])
        stackView.addArrangedSubview(views[1])
        stackView.addArrangedSubview(views[2])
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)

        UIView.animate(withDuration: 0.3) {
            if self.stackView.arrangedSubviews.count == 3 {
                self.views[1].alpha = 0.0
                self.stackView.removeArrangedSubview(self.views[1])
            } else {
                self.views[1].alpha = 1.0
                self.stackView.insertArrangedSubview(self.views[1], at: 1)
            }
            self.stackView.layoutIfNeeded()
        }
    }

}

【讨论】:

  • 但是没有办法不玩约束
  • @Androidteem 有:使用 UIStackView。
  • 我现在在 stackview 中。在阅读了上面的 cmets 之后。我已将 view 1 、 2,3 放在 stackview 中垂直对齐。间距为 10
  • @Androidteem 当然。完全一样。您所做的就是将 view2 作为出口,并以与我相同的方式将其与堆栈视图一起操作。但请确保插座对于您要删除的视图不弱。
  • @Androidteem 重要的是要知道,如果出口很弱,在这种情况下,您不应将其从超级视图中删除或从堆栈视图中删除,因为这样做会将其设置为 nil,因为视图将是解除分配。禁用约束也是如此。
猜你喜欢
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-29
  • 1970-01-01
  • 2017-12-24
相关资源
最近更新 更多