Thinking out loud - Pet project series - 3/x
Just ignore me
Last week we agreed on going with a manual layout. That means our views / controllers are not gonna be instantiated through a NSCoder
-> init(coder:)
is useless right now. But the compiler doesn't know about our decision and complains about missing implementations.
For such use cases I have a handy code snippet up my sleeve:
@available(*, unavailable, message: "This class can not be used in the Interface Builder")
required init?(coder: NSCoder) { fatalError("This class can not be used in the Interface Builder") }
Putting it together
I started to implement an ingredients list table with a collection view (logic...huh). And man! How I enjoy working with a "new" UICollectionViewCompositionalLayout
.
At first glance, it may look java-level-bloated, but nothing that a couple of extensions couldn't fix :D
On second look, creating grid layouts has never been easier.
Oh and just look at this beauty:
Hide it under a rug
Probably the only feature I miss in Swift right now are namespaces (scopes for identifiers to prevent name collisions).
One way to achieve namespace-like behaviour is by using nested types, e.g.:
enum Layouts { }
extension Layouts {
struct MagicLayout { }
}
Layouts.MagicLayout() vs MagicLayout()
For smaller projects it's a question of tidiness and things being in their place.
On bigger projects it's common to have naming issues, when you spend too much time to come up with a name for a thing, cauz you cannot just call it TheThing
(well you can, but just once). But if you already have domain specific namespaces, random TheThing
becomes domain specific as User.TheThing
, Layout.TheThing
or whatever you came up with.
Call me anytime
People tend to put every piece of logic, every single function into some class / struct. Maybe it's a way to avoid "a dirty singleton" bad practices. Or maybe it's thinking something like: "OOP will solve all our problems".
I personally find small pure functions super handy. Especially if you combine them with namespaces from above.
For example, new compositional layouts can be just one global function as:
enum CollectionLayouts { }
extension CollectionLayouts {
enum List {
static func make() -> UICollectionViewLayout {
...
return UICollectionViewCompositionalLayout(section: ...)
}
}
}
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: CollectionLayouts.List.make())
Consuming package
As you remember, SPM is unable to build iOS apps, so we need to create a separate demo project that would add the package as a dependency.
Luckily, Xcode is able to add local dependencies if you use file://
schema:
file:///Users/{username}/broken_dreams/path_to_project/TheProject
If you want to know how it all started, I got you: Starting Pet project series 0/x | ManWithBear
See ya!