Usercentrics UI is a native UI component designed to own all the complexity of compliance, while also allowing different levels of customization.
This component consists of two layers:

Banner first layer
The first layer is designed to be friendly to end-users, compact and highly customizable. This layer can be presented in three different ways:



Recommendation
Use the first layer when collecting consent for the first time or when prompting updates to the consent services. Remember that users will be able to navigate from the first layer to the second layer.
To present the first layer, simply create an instance of UsercentricsBanner, and call showFirstLayer(). Once the user provides their consent choices, a userResponse object will be returned.
let banner = UsercentricsBanner()
banner.showFirstLayer() { userResponse in
// Handle userResponse
}Passing a specific HostView
You may also pass a specific HostView as a parameter of
showSecondLayer(hostView: <UIViewController>). If not provided, the SDK will resolve the HostView from the presented view controller of the first window.
Support for Swift UI
Support for Swift UI is available starting v2.7.6. On our iOS sample app you can find an example of how to integrate with Swift UI.
val banner = UsercentricsBanner(<Context>)
banner.showFirstLayer() { userResponse ->
// Handle userResponse
}Use a valid Context
We are using the
DialogAndroid API for the Banner implementation. It is recommended to use aContextthat is anActivityor derived/wrapper from it. Note that theActivityhas to be alive for the dialog to be displayed.
final userResponse = await Usercentrics.showFirstLayer();
// Handle userResponseconst userResponse = await Usercentrics.showFirstLayer();
// Handle userResponseUsercentrics.Instance.ShowFirstLayer(<UsercentricsLayout>, (userResponse) => {
// Handle userResponse
});Banner second layer
The second layer is designed to own all the complexity of compliance, declare all legally required information and allow for granular choices.

Recommendation
Use the second layer to allow users to review their choices from your apps settings.
To present the second layer, similarly create an instance of UsercentricsBanner, and call showSecondLayer(). The same userResponse object will be returned here as well.
let banner = UsercentricsBanner()
banner.showSecondLayer() { userResponse in
// Handle userResponse
}Passing a specific HostView
You may also pass a specific HostView as a parameter of
showSecondLayer(hostView: <UIViewController>). If not provided, the SDK will resolve the HostView from the presented view controller of the first window.
Support for Swift UI
Support for Swift UI is available starting v2.7.6. On our iOS Sample App you can find an example of how to integrate with SwiftUI.
val banner = UsercentricsBanner(<Context>)
banner.showSecondLayer() { userResponse ->
// Handle userResponse
}Use a valid Context
We are using the
DialogAndroid API for the Banner implementation. It is recommended to use aContextthat is anActivityor derived/wrapper from it. Note that theActivityhas to be alive for the dialog to be displayed.
Restoring unsaved choices after a configuration change (optional)
A configuration change (e.g. toggling dark mode) can recreate the hosting
Activitywhile the Second Layer is open, closing the banner before any unsaved choice is saved. To preserve that in-progress state, pass anonSecondLayerStateSnapshotcallback to capture it, and hold the result somewhere that survives recreation (e.g. aViewModel):banner.showSecondLayer( initialState = pendingSecondLayerState, // null on a fresh show onSecondLayerStateSnapshot = { pendingSecondLayerState = it }, ) { userResponse -> // Handle userResponse }Then, when your
Activityis recreated, pass the stored state back in asinitialStateto reopen the banner exactly as the user left it. This is entirely optional — the existingshowSecondLayer { }call keeps working unchanged if you don't need it.
final userResponse = await Usercentrics.showSecondLayer();
// Handle userResponseconst userResponse = await Usercentrics.showSecondLayer();
// Handle userResponseUsercentrics.Instance.ShowSecondLayer(<showCloseButton>, (userResponse) => {
// Handle userResponse
});Opening the Second Layer on a specific tab (optional)
By default, the Second Layer opens on its first tab. To send users straight to a particular tab (e.g. from a "Manage partners" entry in your app settings), pass the tab parameter:
Value | Opens | Available in |
|---|---|---|
| The Services tab | GDPR and CCPA layouts |
| The Vendors tab | TCF layouts |
Available from SDK version 2.35.0 on iOS, Android, Flutter, React Native and Unity (iOS: since 2.34.0).
let banner = UsercentricsBanner()
banner.showSecondLayer(tab: .services) { userResponse in
// Handle userResponse
}Passing a specific HostView
As with
showSecondLayer(), you may also pass a HostView:showSecondLayer(hostView: <UIViewController>, tab: .services) { ... }.
import com.usercentrics.sdk.models.settings.SecondLayerTab
val banner = UsercentricsBanner(<Context>)
banner.showSecondLayer(SecondLayerTab.SERVICES) { userResponse ->
// Handle userResponse
}final userResponse = await Usercentrics.showSecondLayer(tab: SecondLayerTab.services);
// Handle userResponsetab can be combined with settings (BannerSettings): Usercentrics.showSecondLayer(settings: <BannerSettings>, tab: SecondLayerTab.partners).
import {Usercentrics, SecondLayerTab} from '@usercentrics/react-native-sdk';
const userResponse = await Usercentrics.showSecondLayer(undefined, SecondLayerTab.services);
// Handle userResponseThe tab is the second argument, after the optional BannerSettings.
Usercentrics.Instance.ShowSecondLayer(null, SecondLayerTab.Services, (userResponse) => {
// Handle userResponse
});The first argument is the optional BannerSettings (pass null for the defaults). Works on Android and iOS builds.
Choose the tab that matches your setup
Each tab only exists in its own kind of Second Layer, so use
PARTNERSfor TCF andSERVICESfor GDPR/CCPA. If the Second Layer being shown doesn't have the requested tab (for examplePARTNERSin a GDPR layout), or you passnil/null, it opens on its default tab. The Second Layer is always shown.
Existing showSecondLayer() calls keep working unchanged.
