Demystifying Views in iOS · UINib | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/4518-demystifying-views-in-ios/lessons/7

Hi @catie,

When might nibs be a better choice over the more traditional Views in Storyboard approach? Is there a particular set of scenarios where you’re likely to say “a-ha, this looks like a job for nibs!”

Also, I’m having a hard time understanding how we’re building our subview here. I understand how we’re grabbing the nib, instantiating it and looking through our subviews. I’m confused by what we’re doing with the mapping within the subviews, and as well as what addArrangedSubview is doing (I didn’t find the documentation for it terribly enlightening). Could you clarify those a bit please?

(Apologies in advance, I have a lot of questions in this course. :grimacing:)

You can’t design views in Storyboards without encompassing view controllers. If a view is what you want, nibs are the solution!

There isn’t really a “mapping” of the subviews, hence the underscore that Catie goes over at 4:22. That results in an easy way to get a square grid. Let us know if you have some ideas on how the diagram showing that could be improved!

addArrangedSubview is the API for constructing stack views, the way you otherwise might in Interface Builder (IB example here: https://www.raywenderlich.com/7478-beginning-auto-layout/lessons/3).

Thanks @jessycatterwaul I think I’m getting it now–so would it be fair to say that the let cardViews = subviews.map closure is essentially just a slicker way of instantiating the nibs in one shot rather than in a nested for i in 1…subviews.count loop?

If so, then I think the diagram works great as is, but maybe an explicit nod towards using this convention to replace a loop with a map might help the novices like me. :slight_smile: In fact, I suspect this is a handy convention to use in other loop-simplifying cases, if this is accurate?

You’ve got it. You can think of map as the name for a particular and common type for for loop: one that transforms every element of a sequence into something else. In my opinion, when you need to disregard the elements (with an underscore), that’s when map and for both become a little less clear. And in this case, removing nesting isn’t really possible – you can only exchange one method of iteration for the other.

What we really need in this case is just an iterator. (In Swift, that powers a for-in loop. ) Unfortunately, iterators aren’t commonly needed enough to have warranted bringing up earlier in the learning path. I’m thinking maybe that we should introduce the idea here, and let viewers go explore that documentation I linked to, if they’re interested.

Here’s what the change would look like. I think you’ve got a great understanding of this now, so please let me know if you have a suggestion which you think would be clearer!

let squareGridDimensionIterator = subviews.makeIterator()
for subview in subviews as! [UIStackView] {
  for _ in squareGridDimensionIterator {
    let cardView =
      nib.instantiate(withOwner: owner).first { $0 is FrontCardView }
      as! FrontCardView
    subview.addArrangedSubview(cardView)
  }
}

Also, you may be interested in the indices property. It removes the need to manually define 1...subviews.count or 0..<subviews.count.