
[ad_1]
Understanding through two implementations

SwiftUI is great when it comes to reusing views but creating customizable reusable views can be very difficult as SwiftUI needs to know the type of each view in the view hierarchy at compile time. Let’s consider the following design (the quality of the design is not in question here, only the idea).
There are four toolbars, corresponding to four different screens. They all have some common characteristics like Complete Button and title. Also some screens have one or two custom views on the sides such as tiltI and sizeI indicator as well as color indicatorI and size stepperI,
This toolbar would make a great candidate for a customizable reusable view because we have a common repeating pattern and one applicable concept for each of the non-generic components – custom views can only be to the left and right of the toolbar.
We can do this in two ways.
- Creating a view containing all (custom and generic) views and displaying them based on the configuration model
- By creating a view that describes the base template and accepting custom views as parameters
first approach It’s easy to implement and understand but it’s hard to maintain and add new forms in the long run. First, we must have a model describing all possible layouts.
HeaderViewModel
, Includes any variation of the toolbar, as described in the above code. What we need now is a view that understands this model and can display any combination of views depending on the model configuration.
In the above snippet, HeaderView
, Always Displays the title and conditionally displays on the left button and any custom view based on the model provided.
The problem with this approach is that, if we have a new variation of the toolbar design, we will need to modify both. HeaderView
And this HeaderViewModel
To provide configuration and UI to display.
a better way for the customer HeaderView
To provide a custom left-right view during the initialization phase HeaderView
There will be no need to know anything more than the general UI and general configuration.
second point of view Describes how. customer of HeaderView
Can reuse common UI and functionality and directly build and provide custom controls. This approach is more scalable because custom controls are always provided by the client without the need for any updates. HeaderView
either HeaderViewModel
, This approach is also more flexible as the client only has access to the actual custom view being displayed as opposed to access to the model.
First, we need to make HeaderView
Accept two views describing the left custom view and the right custom view. since HeaderView
We cannot accept just one base type for any view in SwiftUI as we can do with UIView in UIKit (well, technically we can use AnyView
But this comes with a performance penalty and will require the client to wrap the custom view AnyView
which is not ideal), we will add two generic parameters, which conform to the view protocol HeaderView
which will hold the type of view provided by the client.
Comment: SwiftUI needs to know the type of each view in the view hierarchy at compile time, so it is necessary to provide custom view types with common parameters.
here we have an update HeaderView
Which can display any type of view as left control and right control. those kinds of thoughts will always be some sort of Opinion And the customer is responsible for providing it. We pass custom views as closures decorated with viewbuilder characteristic for HeadingView
Initializers to give the client maximum flexibility in conveying the creation of the custom view.
Now the client can provide left and right controls during HeaderView
initialization phase and not excluding any custom view-related functionality,
This approach works great when rendering both left and right views but what about the case when we don’t need both left and right custom views or we don’t need any custom view other than title and left button Is. SwiftUI has us covered with a placeholder view called EmptyView
, we can do a pass EmptyView
For those cases when we don’t need left control, right control or both.
Comment: remember we need to pass something for this rightControls
And leftControls
in order to provide HeaderView
With types for its generic parameters.
As an example, here is Tilt
Toolbar variant initialization that specifies rightControls
and provides EmptyView
for leftControls
,
While this completely solves the problem, it is not ideal as the client needs to take care of implementation details and explicitly pass a EmptyView
Just to satisfy the compiler. There is a cleaner way. We, as the author of HeaderView
, This general case can be addressed in an extension. suppose that LeftControls
Common parameter is a EmptyView
We can provide an initializer that will pass a EmptyView
View header initializers and accept only rightControls
Since then leftControls
already known to be a EmptyView
,
we can create another extension for empty RightControls
As one EmptyView
And for the second case when both the right and left controls should be empty views.
Now we can rewrite Tilt
The header variant allows the client to specify only the view it needs, in a cleaner way, without bothering about its implementation details HeaderView
,
We ended up with a perfect combination of both the approaches. Providing title and left button data via client configuration ViewModel
Because the related views are the same for either type of toolbar and their data is the only non-generic thing. Also, the client provides custom views from only where they are being used and only when they are needed.
You can find a working example describing both approaches GitHub,
[ad_2]
Source link
#Reusable #Customizable #Views #SwiftUI #Petru #Lutenko #August