FAQ
Light and dark theme
There are several approaches when working with different themes.
-
The app's color palette is set on the client.
Create your variable storage
DivVariableStorage
and pass it toDivKitComponents
.let applicationStorage = DivVariableStorage() let themeVariable: DivVariables = [ DivVariableName(rawValue: "palette"): .dict([ "text_color": "#ffffff", "text_background": "#0077FF" ]) ] applicationStorage.put(themeVariable) let variablesStorage = DivVariablesStorage(outerStorage: applicationStorage) let divkitComponents = DivKitComponents(variablesStorage: variablesStorage)
The layout itself will look like this:
{ "card": { "log_id": "text", "states": [ { "state_id": 0, "div": { "type": "text", "text": "Hello, DivKit!", "height": { "type": "fixed", "value": 48 }, "border": { "corner_radius": 16 }, "background": [ { "type": "solid", "color": "@{getColorFromDict(palette, 'text_background')}" } ], "margins": { "top": 20, "left": 20, "right": 20 }, "font_size": 14, "text_alignment_vertical": "center", "text_alignment_horizontal": "center", "text_color": "@{getColorFromDict(palette, 'text_color')}" } } ] } }
Please note that that the JSON layout doesn't know anything about the
palette
variable, and you need to pass it from the client.
To avoid errors, add a default value via thegetOptColorFromDict
function. -
The color palette is set on the server side.
In this case, you need to know which theme is used in the app. To do this, create the global
app_theme
variable:let applicationStorage = DivVariableStorage() let themeVariable: DivVariables = [ DivVariableName(rawValue: "app_theme"): .string("dark") ] applicationStorage.put(themeVariable) let variablesStorage = DivVariablesStorage(outerStorage: applicationStorage) let divkitComponents = DivKitComponents(variablesStorage: variablesStorage)
The layout itself will look like this:
{ "card": { "variables": [ { "name": "palette", "type": "dict", "value": { "light": { "text_color": "#ffffff", "text_background": "#0077FF" }, "dark": { "text_color": "#000000", "text_background": "#0077FF" } } } ], "log_id": "text", "states": [ { "state_id": 0, "div": { "type": "text", "text": "Hello, DivKit!", "height": { "type": "fixed", "value": 48 }, "border": { "corner_radius": 16 }, "background": [ { "type": "solid", "color": "@{getColorFromDict(palette, app_theme, 'text_background')}" } ], "margins": { "top": 20, "left": 20, "right": 20 }, "font_size": 14, "text_alignment_vertical": "center", "text_alignment_horizontal": "center", "text_color": "@{getColorFromDict(palette, app_theme, 'text_color')}" } } ] } }
Troubleshooting in DivKit
To simplify layout debugging on the client, DivKit has an indicator for layout errors. By default, this indicator is disabled. To enable it, additionally pass DebugParams
:
divView.setSource(DivViewSource(kind: .data(jsonData),
cardId: "ExampleCard"),
debugParams: DebugParams(isDebugInfoEnabled: true))
For example, let's pass an invalid value to corner_radius
:
"border": {
"corner_radius": "incorrect_value"
},
An error indicator appears in the layout:
Interacting with it shows you errors in the debug panel.
To log errors, pass the reporter
parameter to DivKitComponents
.
Non-functional visibility_actions
Let's consider a layout where a visibility_action
is called after 1 second, and the button text changes.
{
"card": {
"variables": [
{
"name": "button_text",
"type": "string",
"value": "Waiting visibility action"
}
],
"log_id": "text",
"states": [
{
"state_id": 0,
"div": {
"type": "text",
"text": "@{button_text}",
"height": {
"type": "fixed",
"value": 48
},
"border": {
"corner_radius": 16
},
"background": [
{
"type": "solid",
"color": "#0077FF"
}
],
"margins": {
"top": 20,
"left": 20,
"right": 20
},
"font_size": 14,
"text_alignment_vertical": "center",
"text_alignment_horizontal": "center",
"visibility_actions": [
{
"log_id": "example",
"visibility_duration": 1000,
"url": "div-action://set_variable?name=button_text&value=Visibility%20action%20called!"
}
]
}
}
]
}
}
If nothing is done on the client side, this action
won't be called. DivView
doesn't know how visible it is on the screen. When DivView
becomes visible on the screen, you need to call the onVisibleBoundsChanged
method:
divView.onVisibleBoundsChanged(to: visibleSize)
Does DivKit support the Right-To-Left interface?
Yes. You need to pass the layoutDirection
parameter to DivKitComponents
, and RTL elements will be displayed correctly.
let divkitComponents = DivKitComponents(layoutDirection: .rightToLeft)
Can I use local pictures when working with DivView?
By default, DivKit can load pictures from divkit
to the app's main bundle as URLs in the following format: divkit-asset://image.png
.
You can also write a custom image selection logic. To do this, create your ImageHolderFactory
that can turn a URL into a path to an image in the file system.
let imageHolderFactory = ImageHolderFactory(localImageProvider: self, requestPerformer: URLRequestPerformer(urlTransform: nil))
let divkitComponents = DivKitComponents(imageHolderFactory: imageHolderFactory)
extension ViewController: LocalImageProviding {
func localImage(for url: URL) -> BasePublic.ImageHolder? {
guard url.scheme == "localImage" else { return nil }
return UIImage(named: url.host()!)
}
}
The JSON itself will look like this:
{
"card": {
"log_id": "image",
"states": [
{
"state_id": 0,
"div": {
"type": "container",
"items": [
{
"type": "image",
"image_url": "localImage://image",
"height": {
"type": "match_parent"
}
}
],
"width": {
"type": "match_parent"
},
"height": {
"type": "fixed",
"value": 100
},
"margins": {
"top": 8,
"bottom": 8,
"left": 8,
"right": 8
}
}
}
]
}
}
Learn more
Follow DivKit news in the Telegram channel: http://t.me/divkit_news
You can also discuss topics of interest in the DivKit user community in Telegram: https://t.me/divkit_community_ru