Open ScottRobbins opened 5 years ago
Ignoring settings colors and non views/constraints, one possible direction is to build if statements into the layout:
ViewLayout(view: self.view) { (com) in
com.stackView { (com) in
com.if(/*some condition*/) { (com) in
com.arrangedView(self.myView) { (com) in
...
}
}.elseif(/*some condition*/) { (com) in
...
}.else(/*some condition*/) { (com) in
...
}
}
}
One part of this is that you'd no longer be explicitly calling to update your layout. You're describing it here. This function that describes the layout gets executed once.
So how could this work?
The condition statements inside of the if()
function could require what is passed in to be a function. Something that we can store and later re-evaluate. Ideally these functions would be pure.
One of the tricks already to this framework is that at the call site, no constraints have been activated and no constraints. It also stores all of the decisions about view hierarchy and constraints in a tree of components.
The if statements would mark components under it to be active or inactive. This could be used to get the active constraints and current view layout that could be re-run through the diffing algorithm.
The next thing to solve is how to know when to re-evaluate the layout to make adjustments. The simplest implementation of this is to have each view layout store a single "ViewState" or "ViewModel" object. Require that for this framework to work, the functions inside of if()
functions use data from only the view model. When the view layout's view state changes, it can re-run the decision functions to find what components should be active and automatically update things.
What I see as the pros of this:
Some cons:
There are also a couple concerns:
to handle the other UI stuff, we can probably make some kind of bindings interface: https://www.swiftbysundell.com/posts/bindable-values-in-swift
This doesn't work for all UIKit things because a lot has to be done with closures because UIKit sometimes relies on method calls. But a closure API could be tacked onto that.
I think this would work really well for UI configuration, but can it also work for deciding what path to go down for constraints/subviews being on screen? It's similar to the .if()
I had there.
I think that if I go down this route I should remove the component returns from the APIs. The library will have strong enough opinions that making an opinionated library around it won't be easily possible.
There are also going to be times when you want to bind on multiple properties on a view state and we can't really do variadic generics in that way so you'd need some other type of API.
I think that going with a purely functional approach as I mocked up elsewhere with enums/structs, and using something like .if(
originally brought up in https://github.com/HotCocoaTouch/DeclarativeLayout/issues/31