Swift 从父视图中删除子视图

Swift remove subviews from superview

我有一个 scrollView,我给它添加了一个 refreshcontroll。

self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Frissítéshez húzzad! :)")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.scrollView.addSubview(refreshControl)

在刷新方法中,我必须从滚动视图中删除所有子视图,然后重新填充滚动视图..

self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Frissítéshez húzzad! :)")
self.refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
self.scrollView.addSubview(refreshControl)

在我尝试拉动之后,我的滚动视图获得了新数据,但它不再有刷新控件。我认为这是因为当我从我的滚动视图中删除子视图时,我也从中删除了 refreshcontroll。 (如果我在刷新方法中再次添加 refreshcontroll,我的 scrollview 将再次具有 refreshconroll)但是还有另一个问题。刷新滚动视图后向下移动..我附上图片:

这就是我删除子视图的方式:

func refresh(sender:AnyObject)
{
    //remove all subviews from scrollview..
    let subViews = self.scrollView.subviews
    for subview in subViews{
        println("for removing...")
        subview.removeFromSuperview()
    }

    println("refresh called..")
    UIApplication.sharedApplication().applicationIconBadgeNumber = 0
    //remove all elements from the array
    tstFrames.removeAll(keepCapacity: false)
    //refresh data from webservice and adding it to tstFrames Array
    wsServiceFeedTst()
    //adding items to the scrollview from tstFramesArray
    addPosts()
    self.refreshControl.endRefreshing()

}

这是滚动视图在刷新之前的样子:

这是刷新后的样子:

谁能帮我看看为什么会下降?

谢谢!

谢谢,这是解决方案:

let subViews = self.scrollView.subviews
for subview in subViews{
    println("for removing...")
    if (subview is PostLineItem) {
        subview.removeFromSuperview()
    }
    else {
        println("not removing..")
    }
}

通过删除所有子视图,您还可以删除您明确添加的子视图以外的子视图,例如刷新视图和布局约束。

(为了从评论中回答你的问题,布局约束实际上可以是子视图。我在这里解释了如何删除除布局约束之外的所有子视图:。)

一般来说,我建议更改您的代码以使其更具体,以便仅删除您添加的视图。例如,您可以将标签添加到您在 addPosts 方法中添加的子视图:

post.tag = 1000

然后仅删除 refresh: 中具有该标签的子视图:

let subViews = self.scrollView.subviews
for subview in subViews{
    if subview.tag == 1000 {
        subview.removeFromSuperview()
    }
}

确保您不会删除您自己未明确添加的任何子视图。

编辑:事实证明 OP 添加的子视图都是自定义类型 PostLineItem 所以标签是不必要的,因为我们可以删除所有 PostLineItems 而不是:

for subview in self.view.subviews {
    if subview is PostLineItem {
        subview.removeFromSuperview()
     }
}

我今天也偶然发现了这个问题,想分享我的解决方案。您可以使用 swift 中的以下 UIView 扩展删除一个视图(及其子视图)的所有子视图。此外,我附上了一个以相同方式删除所有约束的解决方案。

extension UIView {

  // Recursive remove subviews and constraints
  func removeSubviews() {
    self.subviews.forEach({
        if !([=10=] is UILayoutSupport) {
            [=10=].removeSubviews()
            [=10=].removeFromSuperview()
        }
    })

  }

  // Recursive remove subviews and constraints
  func removeSubviewsAndConstraints() {
    self.subviews.forEach({
        [=10=].removeSubviewsAndConstraints()
        [=10=].removeConstraints([=10=].constraints)
        [=10=].removeFromSuperview()
    })
  }

}

第一个解决方案将保留所有约束,请参阅 Lyndsey 的回答。请注意,此解决方案会删除 UIView 下的整个层次结构。如果你只想删除特定的子视图交换或像这样扩展:

if !([=11=] is UILayoutSupport) && !([=11=] is PostLineItem)