I have no technical ability. I know nothing about Swift macros. But I have confidence in my taste, and the ability to express what I feel.

Introducing Slots - convenient view slots without the init explosion https://github.com/kylebshr/slots

@kylebshr I did read through the readme before responding. (Twice actually. 🙂)

I’m a little unsure as to how it would handle the EmptyView scenario I mentioned, given you wouldn’t actually store it as nil but as a “slotted type”. In the icon example why is the annotation `.text`? I would expect something like `.empty`, but perhaps I’m completely misunderstanding how this is supposed to work.

@mergesort maybe you can describe what you’re trying to accomplish with EmptyView? Not sure *I* fully understand, but if I do I’ll try to explain it better

@mergesort I think I understand what you’re trying to do, and instead of something like `.empty` I’ve used the type system for this; optional view properties get init variations where they’re omitted from the init, and they get set to nil (and constrained to Never, though you could constraint to EmptyView for the same effect).

I prefer optional views instead of views that may be EmptyView, because you can customize the layout based on their presence instead of checking the type.

@mergesort also, sounds like I need a much better readme
@kylebshr Had to get a code snippet for you, but here's a real world (though oversimplified) example of what I mean, based no how SwiftUI provides multiple initializers for containers like this. https://gist.github.com/mergesort/085eb9986a64f904c17d3c452877d5f9
gist:085eb9986a64f904c17d3c452877d5f9

GitHub Gist: instantly share code, notes, and snippets.

Gist

@mergesort how would you feel if headerView was optional, and instead of where == EmptyView you used where == Never and assigned nil? Ignoring slots for a moment, I think this is a slightly better design that accomplishes the same thing, because internally you might want to adjust layout based on headerViews presence, e.g., in the body:

if let headerView {
Spacer()
headerView
}

@mergesort now, assuming you’re ok with this design (which is just a design choice) yes, slots does exactly what you did in the gist, but automatically
@mergesort another cool think about optional views is you can just place them in the view hierarchy and nil is transformed by the ViewBuilder into EmptyView
@kylebshr I haven’t had a chance to get to a computer and test this but my hesitation is that the pattern SwiftUI uses is the where == EmptyView constraint I’ve chosen, rather than providing nullable views. I’m not sure there is enough difference to skip this suggestion, but:
1. I haven’t considered every scenario so I’m not sure these two options being equivalent always holds true.
2. This scenario feels like something that a macro can handle as well, and IMO may be worth considering for Slots.
@mergesort yeah both patterns are valid, I could easily add a .empty option to slots for anyone who prefers that pattern!
@kylebshr Would love that, would make Slots an instant integration for me on top of the other features it provides. 🙂
Release 0.0.9 · kylebshr/slots

What's New SlotResolver Protocol A new SlotResolver protocol for custom slot resolution strategies, giving you full control over how slots are resolved from child views. Unlabeled Support Added .un...

GitHub
@mergesort you'll find extensions with constraints to optionals, so I think it'll work fine. I think there are internal tools to introspect if a view is EmptyView more easily than we have (or had, we have that new Group API now), so optional wasn't as necessary for internal views.
@kylebshr No shit, never noticed that so it seems like their usage is mixed. But I don't think you need anything special, I just do a check to see if the view is EmptyView.self.
@mergesort yeah I hate runtime type checks like that personally, feels like a code smell/bad practice