Swift从superview中删除子视图

时间:2015-06-14 15:54:23

标签: ios swift uiscrollview uirefreshcontrol

我有一个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)

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

这是我删除子视图的方法:

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()

}

在刷新之前,这是scrollview的样子: enter image description here

这是刷新后的样子: enter image description here

任何人都可以帮我解释为什么会这样下降?

谢谢!

谢谢,这是解决方案:

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

2 个答案:

答案 0 :(得分:14)

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

(并且从评论中回答你的问题,布局约束实际上可以是子视图。我解释了如何删除除布局约束之外的所有子视图:https://stackoverflow.com/a/27281242/2274694。)

通常,我建议您将代码更改为更具体,以便仅删除您添加的视图。例如,您可以为在addPosts方法中添加的子视图添加标记:

post.tag = 1000

然后仅删除refresh:中带有该标记的子视图:

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

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

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

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

答案 1 :(得分:3)

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

extension UIView {

  // Recursive remove subviews and constraints
  func removeSubviews() {
    self.subviews.forEach({
        if !($0 is UILayoutSupport) {
            $0.removeSubviews()
            $0.removeFromSuperview()
        }
    })

  }

  // Recursive remove subviews and constraints
  func removeSubviewsAndConstraints() {
    self.subviews.forEach({
        $0.removeSubviewsAndConstraints()
        $0.removeConstraints($0.constraints)
        $0.removeFromSuperview()
    })
  }

}

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

if !($0 is UILayoutSupport) && !($0 is PostLineItem)