Swift remove subviews from superview
Solution 1
By removing all subviews, you can also be removing subviews other than the ones you explicitly added, like the refresh view and layout constraints.
(And to answer your question from the comments, layout constraints can in fact be subviews. I explain how to remove all subviews except layout constraints here: https://stackoverflow.com/a/27281242/2274694.)
In general, I recommend changing your code to be more specific such that only the views you've added are removed. For example, you could add a tag to the subviews you add in your addPosts
method:
post.tag = 1000
then remove only the subviews with that tag in refresh:
:
let subViews = self.scrollView.subviews
for subview in subViews{
if subview.tag == 1000 {
subview.removeFromSuperview()
}
}
to ensure that you don't remove any subviews you haven't explicitly added yourself.
Edit: It turns out the OP's added subviews are all of custom type PostLineItem
so the tags are unnecessary since we can just remove all the PostLineItem
s instead:
for subview in self.view.subviews {
if subview is PostLineItem {
subview.removeFromSuperview()
}
}
Solution 2
I stumbled about this problem today as well and would like to share my solution. You can remove all subviews of a view (and their subviews) with the following UIView extension in swift. In addition I attached a solution for removing all constraints the same way.
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()
})
}
}
The first solution will keep all contraints, see Lyndseys answer. Be aware that this solution removes the whole hierarchy below the UIView. If you only want to remove specific subviews exchange or extend like this:
if !($0 is UILayoutSupport) && !($0 is PostLineItem)
solarenqu
Updated on December 02, 2020Comments
-
solarenqu over 3 years
i have a scrollView, and i added a refreshcontroll to it.
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)
in the refresh method i have to remove all subviews from the scrollview, then repopulate the scrollview..
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)
after i try to pull, my scrollview get new data but it's don't have anymore refreshcontroll. i think it is because when i removing subviews from my scrollview i also remove the refreshcontroll from it. (if i add the refreshcontroll again in my refresh method my scrollview will have refreshconroll again) But there is another problem. After refreshing my scrollview moving down.. i attached to pictures:
This is how i remove the subiews:
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() }
This is how scrollview look like before refreshing:
An this is how it looks like after refreshing:
could anybody help me about why is this moving down?
Thank you!
Thank you, this is the solution:
let subViews = self.scrollView.subviews for subview in subViews{ println("for removing...") if (subview is PostLineItem) { subview.removeFromSuperview() } else { println("not removing..") } }