GuidesAPI ReferenceRelease Notes
HomeLog InHome
Guides

Moments Widget to Tabs - iOS

The SDK supports launching a fullscreen tabs player directly from a Moments widget tap. Instead of opening a single-moment player, the widget opens the multi-tab BlazeMomentsPlayerContainerTabs experience with all configured tabs.

The widget derives its displayed content from the first tab's data source, so the widget's feed and the first tab in the fullscreen player are always in sync.

❗️

Keep the first tab available for the lifetime of the widget. Removing, hiding, or reordering it can disconnect the widget from the tabs player.

UIKit

Pass your BlazeMomentsPlayerContainerTabs instance to the dedicated initializer on BlazeMomentsWidgetRowView or BlazeMomentsWidgetGridView:

convenience public init(
    layout: BlazeWidgetLayout,
    tabsContainer: BlazeMomentsPlayerContainerTabs,
    cachePolicyLevel: BlazeCachePolicyLevel? = nil,
    perItemStyleOverrides: [BlazeWidgetItemCustomMapping: BlazeWidgetItemStyleOverrides] = [:]
)

Parameters

ParameterTypeDescription
layoutBlazeWidgetLayoutThe layout configuration for the widget.
tabsContainerBlazeMomentsPlayerContainerTabsThe tabs container that drives content and the fullscreen player. The first tab's data source is used by the widget.
cachePolicyLevelBlazeCachePolicyLevel?Optional cache policy override. Defaults to nil.
perItemStyleOverrides[BlazeWidgetItemCustomMapping: BlazeWidgetItemStyleOverrides]Per-item style overrides. Defaults to empty.

Example

let tabs = [
    BlazeMomentsContainerTabItem(
        containerId: "tab-trending",
        title: "Trending",
        dataSource: .labels(.singleLabel("trending"))
    ),
    BlazeMomentsContainerTabItem(
        containerId: "tab-for-you",
        title: "For You",
        dataSource: .labels(.singleLabel("for_you"))
    )
]

let tabsContainer = BlazeMomentsPlayerContainerTabs(
    tabs: tabs,
    tabsStyle: .base(),
    containerTabsDelegate: nil,
    containerSourceId: "moments-widget-tabs-container"
)

let rowWidget = BlazeMomentsWidgetRowView(
    layout: BlazeWidgetLayout.Presets.MomentsWidget.Row.verticalRectangles,
    tabsContainer: tabsContainer
)
rowWidget.embedInView(containerView)
rowWidget.reloadData(progressType: .skeleton)
📘

You must call reloadData after initializing the widget to trigger the first content fetch.

SwiftUI

There are two ways to initialize a tabs-backed BlazeSwiftUIMomentsWidgetViewModel.

Option 1 — BlazeSwiftUIMomentsTabsWidgetConfiguration (recommended)

Use BlazeSwiftUIMomentsTabsWidgetConfiguration to bundle the layout and tabs container into a single configuration object:

public init(
    tabsWidgetConfiguration: BlazeSwiftUIMomentsTabsWidgetConfiguration,
    delegate: BlazeWidgetDelegate? = nil,
    onWidgetItemClickHandler: ((BlazeWidgetItemClickParams) -> BlazeWidgetItemClickHandlerState)? = nil
)

BlazeSwiftUIMomentsTabsWidgetConfiguration

public init(
    layout: BlazeWidgetLayout,
    tabsContainer: BlazeMomentsPlayerContainerTabs,
    perItemStyleOverrides: [BlazeWidgetItemCustomMapping: BlazeWidgetItemStyleOverrides] = [:],
    widgetIdentifier: String = "\(Date().timeIntervalSince1970)",
    isScrolledEnabled: Bool = false,
    cachePolicyLevel: BlazeCachePolicyLevel? = nil,
    isEmbededInScrollView: Bool = false,
    refreshControl: UIRefreshControl? = nil,
    shouldOrderWidgetByReadStatus: Bool = true
)
PropertyTypeDescription
layoutBlazeWidgetLayoutThe layout configuration for the widget.
tabsContainerBlazeMomentsPlayerContainerTabsThe tabs container. The first tab's data source drives the widget's content.
perItemStyleOverrides[BlazeWidgetItemCustomMapping: BlazeWidgetItemStyleOverrides]Per-item style overrides. Defaults to empty.
widgetIdentifierStringUnique widget identifier. Defaults to a timestamp-based string.
cachePolicyLevelBlazeCachePolicyLevel?Optional cache policy override. Defaults to nil.
shouldOrderWidgetByReadStatusBoolWhether to order items by read status. Defaults to true. See Ordering and item limits.

Example

let tabsContainer = BlazeMomentsPlayerContainerTabs(
    tabs: tabs,
    tabsStyle: .base(),
    containerTabsDelegate: nil,
    containerSourceId: "moments-widget-tabs-container"
)

let tabsWidgetConfig = BlazeSwiftUIMomentsTabsWidgetConfiguration(
    layout: BlazeWidgetLayout.Presets.MomentsWidget.Row.verticalRectangles,
    tabsContainer: tabsContainer
)

let viewModel = BlazeSwiftUIMomentsWidgetViewModel(
    tabsWidgetConfiguration: tabsWidgetConfig
)

BlazeSwiftUIMomentsRowWidgetView(viewModel: viewModel)

Option 2 — widgetConfiguration + tabsContainer

Alternatively, pass a BlazeSwiftUIWidgetConfiguration alongside the tabs container directly:

public init(
    widgetConfiguration: BlazeSwiftUIWidgetConfiguration,
    tabsContainer: BlazeMomentsPlayerContainerTabs,
    delegate: BlazeWidgetDelegate? = nil,
    onWidgetItemClickHandler: ((BlazeWidgetItemClickParams) -> BlazeWidgetItemClickHandlerState)? = nil
)
ParameterTypeDescription
widgetConfigurationBlazeSwiftUIWidgetConfigurationWidget layout and configuration settings. The data source is overridden by the first tab's data source.
tabsContainerBlazeMomentsPlayerContainerTabsThe tabs container that drives content and the fullscreen player.
delegateBlazeWidgetDelegate?Optional widget delegate. Defaults to nil.
onWidgetItemClickHandler((BlazeWidgetItemClickParams) -> BlazeWidgetItemClickHandlerState)?Optional click handler. Return .handledByApp to manage the tabs flow yourself.

Example

let viewModel = BlazeSwiftUIMomentsWidgetViewModel(
    widgetConfiguration: BlazeSwiftUIWidgetConfiguration(
        layout: BlazeWidgetLayout.Presets.MomentsWidget.Row.verticalRectangles
    ),
    tabsContainer: tabsContainer
)

BlazeSwiftUIMomentsRowWidgetView(viewModel: viewModel)

Notes

  • The widget always displays content from the first tab's data source. Ensure the first tab is always populated and visible.
  • Return .handledByApp from onWidgetItemClickHandler to opt out of the SDK-managed fullscreen tabs presentation and drive your own embedded tabs flow.
  • For full BlazeMomentsPlayerContainerTabs API reference, see Moments Player Tabs Container.

Did this page help you?