如何在Swift中删除视图的所有子视图?

时间:2014-06-19 17:26:23

标签: macos view swift

我正在寻找一种简单的方法来立即从超视图中删除所有子视图,而不是逐个删除它们。

//I'm trying something like this, but is not working
let theSubviews : Array = container_view.subviews
for (view : NSView) in theSubviews {
    view.removeFromSuperview(container_view)
}

我缺少什么?

更新

我的应用有一个主container_view。我必须将不同的其他视图添加为container_view的子视图,以便提供一种导航。

所以,当点击按钮时,打开"在特定页面中,我需要删除所有子视图并添加新视图。

更新2 - 工作解决方案(OS X)

我猜Apple修好了它。

现在比以往任何时候都更容易,只需致电:

for view in containerView.subviews{
    view.removeFromSuperview()
}

22 个答案:

答案 0 :(得分:302)

编辑:(感谢Jeremiah / Rollo)

到目前为止,在Swift for iOS中执行此操作的最佳方法是:

view.subviews.forEach({ $0.removeFromSuperview() }) // this gets things done
view.subviews.map({ $0.removeFromSuperview() }) // this returns modified array

^^这些功能很有趣!

let funTimes = ["Awesome","Crazy","WTF"]
extension String { 
    func readIt() {
        print(self)
    }
}

funTimes.forEach({ $0.readIt() })

////结束编辑

这样做:

for view in self.view.subviews {
    view.removeFromSuperview()
}

或者,如果您正在寻找特定的课程

for view:CustomViewClass! in self.view.subviews {
        if view.isKindOfClass(CustomViewClass) {
            view.doClassThing()
        }
    }

答案 1 :(得分:32)

对于iOS / Swift,要摆脱我使用的所有子视图:

for v in view.subviews{
   v.removeFromSuperview()
}

删除特定类的所有子视图(如UILabel)我使用:

for v in view.subviews{
   if v is UILabel{
      v.removeFromSuperview()
   }
}

答案 2 :(得分:29)

代码可以更简单地编写如下。

view.subviews.forEach { $0.removeFromSuperview() }

答案 3 :(得分:15)

这应该是最简单的解决方案。

let container_view: NSView = ...
container_view.subviews = []

(其他方法见Remove all subviews?


请注意,这是 MacOS 问题,此答案仅适用于 MacOS 。它不适用于iOS。

答案 4 :(得分:9)

试试这个:

for view in container_view.subviews {
    view.removeFromSuperview()
}

答案 5 :(得分:9)

我不知道你是否设法解决了这个问题,但我最近遇到了类似的问题,For循环每次都会留下一个视图。我发现这是因为当调用removeFromSuperview()时,self.subviews被突变(可能)。

为了解决这个问题我做了:

let subViews: Array = self.subviews.copy()
for (var subview: NSView!) in subViews
{
    subview.removeFromSuperview()
}

通过执行.copy(),我可以在改变self.subviews数组时执行每个子视图的删除。这是因为复制的数组(subViews)包含对象的所有引用,并且不会发生变异。

编辑:在你的情况下,我认为你会使用:

let theSubviews: Array = container_view.subviews.copy()
for (var view: NSView!) in theSubviews
{
    view.removeFromSuperview()
}

答案 6 :(得分:8)

删除所有子视图的扩展程序,它会被快速删除。

import Foundation
import UIKit

extension UIView {
    /// Remove allSubView in view
    func removeAllSubViews() {
        self.subviews.forEach({ $0.removeFromSuperview() })
    }

}

答案 7 :(得分:6)

试试这个:

var subViews = parentView.subviews as Array<UIView>

      for someView in subViews
      {
          someView.removeFromSuperview()
      }

更新:如果您有冒险精神,那么您可以在UIView上进行扩展,如下所示:

extension UIView
{
    func removeAllSubViews()
    {
       for subView :AnyObject in self.subviews
       {
            subView.removeFromSuperview()
       }
    }

}

并称之为:

parentView.removeAllSubViews()

答案 8 :(得分:5)

在xcodebeta6中,这就解决了。

    var subViews = self.parentView.subviews
    for subview in subViews as [UIView]   {
        subview.removeFromSuperview()
    }

答案 9 :(得分:3)

我写了这个扩展名:

extension UIView {
    func lf_removeAllSubviews() {
        for view in self.subviews {
            view.removeFromSuperview()
        }
    }
}

这样您就可以在UIViewController中使用self.view.lf_removeAllSubviews。我稍后会把这个放在我的https://github.com/superarts/LFramework的快速版本中,当时我有更多的swift经验(到目前为止1天exp,是的,对于API,我放弃了下划线)。

答案 10 :(得分:2)

你必须尝试这个

func clearAllScrollSubView ()
{
    let theSubviews = itemsScrollView.subviews

    for (var view) in theSubviews
    {

        if view is UIView
        {
            view.removeFromSuperview()
        }

    }
}

答案 11 :(得分:2)

您的语法略有偏差。确保明确投射。

 let theSubviews : Array<NSView> = container_view.subviews as Array<NSView>
 for view in theSubviews {
     view.removeFromSuperview()
 }

答案 12 :(得分:2)

Swift 3

如果您在视图中添加标记,则可以删除特定视图。

for v in (view?.subviews)!
{
    if v.tag == 321
    {
         v.removeFromSuperview()
    }
 }

答案 13 :(得分:1)

试试这个,我测试了这个:

  let theSubviews = container_view.subviews
  for subview in theSubviews {
      subview.removeFromSuperview()
  }

答案 14 :(得分:1)

仅删除特定类的子视图 - 这是在Xcode6.1.1中为我工作的唯一Swift代码。 假设您要删除的唯一子视图的类型为 UIButton ...

for subView in nameofmysuperview.subviews {
    if subView.isKindOfClass(UIButton) {
        subView.removeFromSuperview()
    }
}

答案 15 :(得分:1)

一衬垫:

while(view.subviews.count > 0) {(view.subviews[0] as NSView).removeFromSuperview()}

我认为这种方法比使用地图 forEach 的“单行”更具可读性。简短的 foreach map 可能难以理解,因为逻辑更抽象。

答案 16 :(得分:1)

对于Swift 3

我做了如下操作,因为只是从superview中删除没有删除数组中的按钮。

    for k in 0..<buttons.count {

      buttons[k].removeFromSuperview()

    }


    buttons.removeAll()

答案 17 :(得分:1)

对于Swift 4.+

extension UIView {
     public func removeAllSubViews() {
          self.subviews.forEach({ $0.removeFromSuperview() })

}

我希望这对您有用。

答案 18 :(得分:1)

Swift 5.0

我创建2种不同的方法来删除子视图。如果将它们放在extension

中,使用起来会容易得多
extension UIView {
    /// Remove all subview
    func removeAllSubviews() {
        subviews.forEach { $0.removeFromSuperview() }
    }

    /// Remove all subview with specific type
    func removeAllSubviews<T: UIView>(type: T.Type) {
        subviews
            .filter { $0.isMember(of: type) }
            .forEach { $0.removeFromSuperview() }
    }
}

答案 19 :(得分:0)

这是另一种方法,它允许您对任何 UIView 实例(或 UIView 子类)的集合调用操作。这样可以轻松地在 filter 之后插入 .subviews 之类的内容,以便您更有选择性,或者在其他 UIView 集合上调用它。

extension Array where Element: UIView {
  func removeEachFromSuperview() {
    forEach {
      $0.removeFromSuperview()
    }
  }
}

示例用法:

myView.subviews.removeEachFromSuperview()

// or, for example:

myView.subivews.filter { $0 is UIImageView }.removeEachFromSuperview()

或者,您可以使用 UIView 扩展完成同样的事情(尽管不能在某些 UIView 实例的任意数组上调用):

extension UIView {
    func removeSubviews(predicate: ((UIView) -> Bool)? = nil) 
        subviews.filter(
            predicate ?? { _ in true }
        ).forEach {
            $0.removeFromSuperview()
        }
    }
}

示例用法:

myView.removeSubviews()
myView.removeSubviews { $0 is UIImageView }

答案 20 :(得分:0)

这是您一直在寻找的单线:

view.subviews.filter({$0.tag == 321}).forEach({$0.removeFromSuperview()})

在使用此代码删除视图之前,不要忘记标记您的视图 (someView.tag = 321)。

答案 21 :(得分:-2)

你尝试过像

这样的事吗?
for o : AnyObject in self.subviews {
     if let v = o as? NSView {
         v.removeFromSuperview()
     }
}