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鈥檙e likely to say 鈥渁-ha, this looks like a job for nibs!鈥

Also, I鈥檓 having a hard time understanding how we鈥檙e building our subview here. I understand how we鈥檙e grabbing the nib, instantiating it and looking through our subviews. I鈥檓 confused by what we鈥檙e doing with the mapping within the subviews, and as well as what addArrangedSubview is doing (I didn鈥檛 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鈥檛 design views in Storyboards without encompassing view controllers. If a view is what you want, nibs are the solution!

There isn鈥檛 really a 鈥渕apping鈥 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鈥檓 getting it now鈥搒o 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鈥ubviews.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鈥檝e 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鈥檚 when map and for both become a little less clear. And in this case, removing nesting isn鈥檛 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鈥檛 commonly needed enough to have warranted bringing up earlier in the learning path. I鈥檓 thinking maybe that we should introduce the idea here, and let viewers go explore that documentation I linked to, if they鈥檙e interested.

Here鈥檚 what the change would look like. I think you鈥檝e 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.