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
| Parameter | Type | Description |
|---|---|---|
| layout | BlazeWidgetLayout | The layout configuration for the widget. |
| tabsContainer | BlazeMomentsPlayerContainerTabs | The tabs container that drives content and the fullscreen player. The first tab's data source is used by the widget. |
| cachePolicyLevel | BlazeCachePolicyLevel? | 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 callreloadDataafter 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
)| Property | Type | Description |
|---|---|---|
| layout | BlazeWidgetLayout | The layout configuration for the widget. |
| tabsContainer | BlazeMomentsPlayerContainerTabs | The tabs container. The first tab's data source drives the widget's content. |
| perItemStyleOverrides | [BlazeWidgetItemCustomMapping: BlazeWidgetItemStyleOverrides] | Per-item style overrides. Defaults to empty. |
| widgetIdentifier | String | Unique widget identifier. Defaults to a timestamp-based string. |
| cachePolicyLevel | BlazeCachePolicyLevel? | Optional cache policy override. Defaults to nil. |
| shouldOrderWidgetByReadStatus | Bool | Whether 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
)| Parameter | Type | Description |
|---|---|---|
| widgetConfiguration | BlazeSwiftUIWidgetConfiguration | Widget layout and configuration settings. The data source is overridden by the first tab's data source. |
| tabsContainer | BlazeMomentsPlayerContainerTabs | The tabs container that drives content and the fullscreen player. |
| delegate | BlazeWidgetDelegate? | 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
.handledByAppfromonWidgetItemClickHandlerto opt out of the SDK-managed fullscreen tabs presentation and drive your own embedded tabs flow. - For full
BlazeMomentsPlayerContainerTabsAPI reference, see Moments Player Tabs Container.
Updated 22 days ago
