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
所以标签是不必要的,因为我们可以删除所有 PostLineItem
s 而不是:
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)
我有一个 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
所以标签是不必要的,因为我们可以删除所有 PostLineItem
s 而不是:
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)