Swift에서 뷰의 모든 하위 뷰를 제거하는 방법은 무엇입니까?


176

하위 뷰를 하나씩 제거하는 대신 슈퍼 뷰에서 모든 하위 뷰를 한 번에 제거하는 간단한 방법을 찾고 있습니다.

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

애플이 고쳤다 고 생각합니다.

이제는 그 어느 때보 다 쉬워졌습니다.

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

2
: 나는 넝마와 함께 장사하면서, 우수한 대답은, 그 @의 sulthan의 답변을 지적하고 싶습니다 stackoverflow.com/questions/24312760/...
크리스토퍼 Swasey

@ChristopherSwasey Swift 4는 오류를 발생시킵니다 : 속성에 할당 할 수 없습니다 : 'subviews'는 가져 오기 전용 속성입니다. :(
William T. Mallard

2
@ WilliamT.Mallard이 방법과 질문이 iOS가 아닌 MacOS에 관한 것이라는 점을 몇 번이나 반복해야합니까?
Fogmeister

답변:


358

편집 : (예레미야 / 롤로 감사)

iOS 용 Swift에서이를 수행하는 가장 좋은 방법은 다음과 같습니다.

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

Xcode 7.0 베타 6에서는 "map '에 대한 호출 결과가 사용되지 않습니다"라는 경고가 생성됩니다. 이것이 최종 버전에서 수정되기를 바랍니다.
Ferschae Naej

나는 또한 그것을 알아 차렸다! Xcode가 베타 버전에서 나오고 문제가 계속되면 게시물을 업데이트하겠습니다.
Bseaborn

8
경고 result of call to 'map' is unused 는 오류가 아닙니다. Array.map대부분의 언어에서 수정 된 배열을 반환합니다. 배열을 반환하지 않는 동등한 방법은입니다 view.subviews.forEach.
Rollo

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

나는 이것이 "Swift에서 이것을하는 가장 좋은 방법"이라고 주장 할 것이다. stackoverflow.com/a/24314054/1974224
Cristik

41

iOS / Swift의 경우 내가 사용하는 모든 하위 뷰를 제거하려면 다음을 수행하십시오.

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

UILabel과 같은 특정 클래스의 모든 하위 뷰를 제거하려면 다음을 사용하십시오.

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

31

코드는 다음과 같이 간단하게 작성할 수 있습니다.

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

18

이것이 가장 간단한 해결책이어야합니다.

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

( 다른 방법은 모든 하위 보기 제거? 를 참조 하십시오 )


이것은 참고 맥 OS 질문이 대답에 대해서만 작동 맥 OS . iOS에서는 작동하지 않습니다.


이것은 가장 간단한 방법입니다 ... removeFromSuperview는 더 이상 하위 뷰 배열에없는 각 뷰에 대해 자동으로 호출됩니다.
Christopher Swasey 2016 년

2
@datayeah 그것들은 아니지만 NSView(OS X)와 UIView(iOS) 사이에는 큰 차이가 있습니다.
Sulthan

@Sulthan 당신이 맞아요. UIView에 대한 Swift 답변을 보러 왔으며 전체 코드 스 니펫을 읽지
못했습니다

1
스위프트 4 오류 : 속성에 할당 할 수 없습니다 : 'subviews'는 get-only 속성입니다. :(
William T. Mallard

1
@AmrAngry 다시 말씀 드리지만, 이것은 NSViewiOS 및에 대한 것이 아니라 항상 Mac OS 질문이었습니다 UIView. 사람들은 질문과 태그를 읽을 필요가 없으므로 iOS 답변으로 채워졌습니다.
Sulthan

10

이 문제를 해결할 수 있었는지 모르겠지만 최근에 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()
}

잘 작동합니다! 감사합니다
Alberto Bellini

: 아마이 할 수있는 훨씬 더 우아한 방법이 있지만 안녕하세요, 다음을 시도 let subViewsArray: Array = (parentView.subviews as NSArray).copy() as Array<NSView>
아담 리차드

9

이 시도:

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

9

모든 서브 뷰를 제거하기위한 확장 기능으로 빠르게 제거됩니다.

import Foundation
import UIKit

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

}

1
왜지도? 아마도? subviews.forEach {$ 0.removeFromSuperview ()}
Zaporozhchenko Oleksandr

1
네 맞아요 @Aleksandr 저는이 글을 쓰고있을 때 커피를
먹지 않았다고

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

2 작은 것 : 나는 osx에서 일하고 있으므로 <NSView> 맞습니까? 그런 다음 "치명적인 오류 : 배열 인덱스가 범위를 벗어났습니다"가 표시
Alberto Bellini

예, OSX에서는 NSView라고 생각합니다. 치명적인 오류는 어디에서 발생합니까?
azamsharp

부모 뷰에 자식 요소가 있습니까?
azamsharp

응! 나는 1 얻을에 println (parentView.subviews)를 한 경우
알베르토 벨리니

이상하다! 일반적으로 범위를 벗어남은 존재하지 않는 인덱스에 액세스하고 있음을 의미하며 일반적으로 인덱스가 i ++과 같은 for 루프를 사용하여 발생한다고 생각합니다.
azamsharp

5

xcodebeta6에서는이 문제가 해결되었습니다.

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

그것은 iOS입니다. 나는 OS X에 대한 해결책이 필요
알베르토 벨리니

IOS +1위한 훌륭한 솔루션
inVINCEable

3

나는이 확장을 썼다 :

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

따라서 UIViewController에서 self.view.lf_removeAllSubviews를 사용할 수 있습니다. 나는 스위프트에 대한 더 많은 경험이있을 때 나중에 https://github.com/superarts/LFramework 의 스위프트 버전에 이것을 넣을 것입니다 (1 일 exp, API의 경우 밑줄을 포기했습니다).


3

스위프트 3

뷰에 태그를 추가하면 특정 뷰를 제거 할 수 있습니다.

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

왜 안돼 view.subviews.filter({$0.tag != 321}).forEach({$0.removeFromSuperview()})?
AlexanderZ

3

스위프트 5

하위보기를 제거하는 두 가지 방법을 만듭니다. 그리고 우리가 그것들을 넣으면 사용하기가 훨씬 쉽습니다.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() }
    }
}

2

구문이 약간 벗어났습니다. 명시 적으로 캐스트하십시오.

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

@David 예, FoxNos의 초기 코드에 최대한 가깝게 유지하려고 노력했습니다.
Jack

2

당신은 이것을 시도해야

func clearAllScrollSubView ()
{
    let theSubviews = itemsScrollView.subviews

    for (var view) in theSubviews
    {

        if view is UIView
        {
            view.removeFromSuperview()
        }

    }
}

NS가 아닌 UI입니다. 여기에서 우리는 NS로 UI를 대체하여 그것으로도 작동하는 OS X의 경우에 대해 얘기하고, 내 나쁜, 당신은 :) 옳았다
알베르토 벨리니

1

특정 클래스의 하위 뷰 만 제거하기 위해 이것은 Xcode6.1.1에서 나를 위해 일한 유일한 Swift 코드였습니다. 제거하려는 유일한 하위보기가 UIButton 유형이라고 가정합니다 ...

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

1

짧막 한 농담:

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

이 접근법은 map 또는 forEach를 사용하는 "한 줄짜리"보다 더 읽기 쉽다고 생각합니다 . 논리가 더 추상적이기 때문에 짧은 foreach 을 이해하기 어려울 수 있습니다.


1

스위프트 3

superview에서 제거해도 배열에서 버튼이 지워지지 않기 때문에 다음과 같이했습니다.

    for k in 0..<buttons.count {

      buttons[k].removeFromSuperview()

    }


    buttons.removeAll()

1

이것을 시험해보십시오, 나는 이것을 시험했습니다 :

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

1

에 대한 Swift 4.+

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

}

나는 이것이 당신을 위해 전체 사용되기를 바랍니다.


-2

당신은 같은 것을 시도 했습니까

for o : AnyObject in self.subviews {
     if let v = o as? NSView {
         v.removeFromSuperview()
     }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.