15

I'm trying something like this in Swift but not working. Error is: Type () does not conform to type BooleanType

//visibleCollectionReusableHeaderViews is of type NSMapTable!

var enumerator: NSEnumerator = visibleCollectionReusableHeaderViews.objectEnumerator()
var myValue: AnyObject!

while (( myValue = enumerator.nextObject()))
{

}

What am I doing wrong? I don't think I understand how to iterate over an NSMapTable, or even just to get the first item in it.

Mick MacCallum
  • 126,953
  • 40
  • 282
  • 279
NullHypothesis
  • 4,118
  • 5
  • 34
  • 73

3 Answers3

18

In Swift, this is done using conditional assignment.

let enumerator = visibleCollectionReusableHeaderViews.objectEnumerator()

while let myValue: AnyObject = enumerator.nextObject() {
    println(myValue)
}

Note the non optional type for myValue. Otherwise this loop would be infinite as myValue continued to accept nil objects.

Mick MacCallum
  • 126,953
  • 40
  • 282
  • 279
  • Thanks this did it! By any chance, know of any way to now update a section in a uicollectionview? myValue actually is my header reusable view UICollectionElementKindSectionHeader so i'd like to visually redraw the items in there (the manual constraints need a refresh). I can do uicollectionview.reloaddata() but it's a little slow and redraws the ENTIRE view when I just need the header. – NullHypothesis Aug 25 '14 at 14:18
  • @user3379785 Well, if you're okay with reloading the entire section, you could use `collectionView.reloadSections(NSIndexSet(index: someIndexInteger))`, but if you're only interested in reloading the header, then I'm not exactly sure. It does look like a few options are explored here though. http://stackoverflow.com/questions/13831035/reload-uicollectionview-header-or-footer – Mick MacCallum Aug 25 '14 at 14:23
  • 3
    You will need to put `enumator.nextObject() as? YourObject` if you want to use methods on YourObject, for example. – theblang Jun 01 '15 at 02:10
3

Or a clearer and shorter approach (Swift 3):

for key in table.keyEnumerator() {
    print(key)
}

for object in table.objectEnumerator() ?? NSEnumerator() {
    print(object)
}
Ian Bytchek
  • 8,424
  • 5
  • 40
  • 71
-1

In Swift 3 you can use for-in loop through allObjects property:

for myValue in visibleCollectionReusableHeaderViews.allObjects {
  // do stuff
} 
kelin
  • 10,251
  • 6
  • 69
  • 98
  • Wouldn't this impact performance a considerable amount compared to using a `while` loop? – Zoyt Jun 13 '17 at 00:07
  • 1
    Well a `for-in` loop is faster, because it can be efficiently parallelized. So, if you want to do some really costing stuff inside the loop, this way should be preferred. But we don't know, how `allObjects` property is composed. Probably, calling this property may cause an overhead. But I think, `NSMapTable` has an array inside anyway, and when we access the `allObjects`, we really get an immutable copy. Such operation shouldn't be expensive. – kelin Jun 13 '17 at 13:49
  • 1
    `NSMapTable` has no member `allObjects` – Andreas Ley Jun 28 '17 at 20:30
  • @AndreasLey, really, it's a property of `NSHashTable`. – kelin Jun 28 '17 at 20:39
  • @kelin but `allObjects` is not a property of `NSMapTable`, which is what is being discussed in this question – gyratory circus May 11 '18 at 00:45