37

In Objective-C I'm using this code to remove any sub-views:

[self.view.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];

But how to use it in swift? I saw apple documentation to use that method in swift

func makeObjectsPerformSelector(_ aSelector: Selector)

but when I try it, I get an error: 'AnyObject[]' does not have a member named 'makeObjectsPerformSelector'

Are there any ways to remove sub-views in swift?

Neeku
  • 3,646
  • 8
  • 33
  • 43
yumugee
  • 993
  • 3
  • 9
  • 13

3 Answers3

100

Use forEach:

self.view.subviews.forEach { subview in
    subview.removeFromSuperview()
}

Or like this:

view.subviews.forEach { $0.removeFromSuperview() }
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • ah, I didn't realize I read the documentation about NSArray and not Array in swift. thank you very much – yumugee Jun 27 '14 at 07:40
  • Hmm... The second version (using `map`) crashes for me. I haven't figured out why yet. But the first version (using a cast) works, so just use that. ;^) – rob mayoff Jun 27 '14 at 07:41
  • Map is a piece of cake! – Rubycon Jun 27 '14 at 07:45
  • I think the map() variant is a nice idea but won't fly - at least for NSArray's. Map has to return a value (it maps the value of a collection to another value). If the function you are calling is void (like removeFromSuperview()) - what is the resulting array to contain? (empty tuple 'object'?) This might work but is ugly: .map { e -> String in e.removeFromSuperview(); return "" } – hnh Jun 28 '14 at 08:42
  • 2
    map is used to construct a new array from an old array, so the block is suppose to return a value used for the new array. There doesn't seem to be a make objects perform equivalent, you can just use 'for obj in array {...}', also its probable not safe to modify an array while enumerating over it like that. – Nathan Day Jun 28 '14 at 10:13
  • and the mapping crashes swift every time *sigh*. I had to bridge to a NSArray >. – TheCodingArt Jul 06 '14 at 15:18
  • As of beta 5, `makeObjectsPerformSelector` joins the other `performSelector`-based API as being unavailable to Swift. Use a `for`-`in` loop instead: `for subview in view.subviews { subview.removeFromSuperview() }` Or, if you must, one of the functional-programming-style constructs (`map`, `filter`, `find`) -- but be aware that many consider it bad style to use those for nonfunctional work (i.e. work that has side effects). – rickster Aug 04 '14 at 21:26
  • 1
    As of Swift 2.0, `forEach` is provided natively. E.g. `view.subviews.forEach {$0.removeFromSuperview()}` – Tommy Sep 15 '15 at 11:41
1

It only works on NSArray and NSMutableArray objects.

This will work:

let ar: NSArray = [obj1, obj2, obj3]
ar.makeObjectsPerformSelector("someSelector")

Note that if you have an Array<AnyObject> you can freely convert to NSArray and vise versa.

let anNSArray: NSArray = anArrayOfAnyObject
anNSArray.makeObjectsPerformSelector( "someSelector")
Bruce1q
  • 504
  • 4
  • 8
1

As of Xcode 7, the full family of performSelector methods are available in Swift, including makeObjectsPerformSelector() for NSArray.

FizzBuzz
  • 764
  • 6
  • 16