如何删除视图和更新约束?

Posted

技术标签:

【中文标题】如何删除视图和更新约束?【英文标题】:How to remove a view and update constraints? 【发布时间】:2017-06-15 12:26:25 【问题描述】:

我有一个视图,我正在通过 xib 以编程方式在添加按钮上创建另一个视图。我可以在点击添加更多按钮时创建多个视图,如果我删除最后一个视图,删除也可以工作,但是由于缺少约束视图没有正确更新,中间视图出现问题下面是图像的外观

在开始视图看起来像这样

添加更多视图后

移除中间视图后

删除按钮代码

@IBAction func deletebnt(_ sender: UIButton) 
        let view = self.superview
        let index =  view?.subviews.index(of:self)!
        delegate.txtcheck(text: countstr)
         self.view.removeFromSuperview()
    

添加按钮代码

@IBAction func addMoreBnt(_ sender: UIButton) 
      for constraint in addSuperview.constraints 
            if constraint.firstAttribute == NSLayoutAttribute.height
            
                constraint.constant +=  45
                space = constraint.constant
            
        
        let newView : AvalabileTimeView = AvalabileTimeView()
        newView.frame = CGRect(x: self.addsubView.frame.origin.x, y: 70, width: addsubView.frame.size.width, height:addsubView.frame.size.height)
        newView.delegate = self as AvalabileTimeDelegate
        addSuperview.addSubview(newView)
        let index = addSuperview.subviews.index(of: newView)!        
        newView.translatesAutoresizingMaskIntoConstraints = false
        let heightConstraint = newView.widthAnchor.constraint(equalToConstant:addsubView.frame.size.width )
        let widthConstaint = newView.heightAnchor.constraint(equalToConstant:31 )
        let topConstraint = newView.topAnchor.constraint(equalTo: addSuperview.topAnchor, constant: space - 31)  NSLayoutConstraint.activate([heightConstraint,topConstraint,widthConstaint])

    

委托改变superview的高度

func txtcheck(text: String!) 
        print(text)
        for constraint in addSuperview.constraints 
            if constraint.firstAttribute == NSLayoutAttribute.height
            
                constraint.constant -=  45
                // Here I have to set constraint for bottom view and topview of deleted view but I don't know how to do
            
        
    

这里是演示项目的链接 https://github.com/logictrix/addFieldDemo

【问题讨论】:

使用 UITabelView。您可以非常轻松地实现这种类型的操作。 @Ujesh 是的,如果我无法解决这个问题,我必须使用其他选项,现在我正在尝试解决这个问题。 这个当然可以修复,但是最好使用TableView,如果这是无法使用TableViews的作业,可以理解。否则,请始终使用 Apple 为您提供的最佳工具。 @CoderFrom94 这不是分配,但如果我使用 tableview,我必须从一开始就为整个 ViewController 设计和编码,如果我可以通过一些帮助快速解决这个问题,我不想这样做 TableView 对于 full 界面可能是一个好主意,但是尝试为该部分添加 TableView 将很难工作(内部的垂直滚动表格视图一个垂直滚动的滚动视图)。 【参考方案1】:

不要为每个新的AvalabileTimeView 添加自己的约束,而是使用UIStackView - 您可以删除几乎所有现有代码以添加/删除新视图。

看看.addArrangedSubview().removeArrangedSubview()

这是一些示例代码...您需要在 Interface Builder 中添加一个 UIStackView,将其连接到 Outlet,并调整约束,但仅此而已:

// in ViewController.swift

@IBOutlet weak var availableTimeStackView: UIStackView!

@IBAction func addMoreBnt(_ sender: UIButton) 

    // instantiate a new AvalabileTimeView
    let newView : AvalabileTimeView = AvalabileTimeView()

    // set its delegate to self
    newView.delegate = self as AvalabileTimeDelegate

    // add it to the Stack View
    availableTimeStackView.addArrangedSubview(newView)

    // standard for auto-layout
    newView.translatesAutoresizingMaskIntoConstraints = false

    // only constraint needed is Height (width and vertical spacing handled by the Stack View)
    newView.heightAnchor.constraint(equalToConstant: 31).isActive = true



// new delegate func
func removeMe(_ view: AvalabileTimeView) 

    // remove the AvalabileTimeView from the Stack View
    availableTimeStackView.removeArrangedSubview(view)



// in AvalabileTimeView.swift

protocol AvalabileTimeDelegate
    // don't need this anymore
    func txtcheck(text: String!)

    // new delegate func
    func removeMe(_ view: AvalabileTimeView)


@IBAction func deletebnt(_ sender: UIButton) 
    delegate.removeMe(self)

【讨论】:

感谢您提醒我有关堆栈视图的信息,我完全忘记了它可能会解决我的问题,我会检查并告诉您

以上是关于如何删除视图和更新约束?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AutoLayout 根据父高度调整子视图高度而不添加/删除约束

以编程方式从超级视图中删除视图后更新约束/框架(自动布局)

如何解决这个问题 - 无法删除或更新父行:外键约束失败

如何检查视图中是不是已经存在约束?

SQL表与表之间建立外键约束之后,怎么建立连级更新和删除?

删除中间视图时自动布局折叠空间