GuidesAPI ReferenceRelease Notes
HomeLog InHome
Guides

Moments Player Tabs Container

The Blaze SDK provides a specialized container for displaying content in tabs:

BlazeMomentsPlayerContainerTabs - A class designed to manage and facilitate the playback of moments organized in tabs. Each tab can have its own data source, title, and configuration. The container provides a rich set of features for controlling tab visibility, selection, and player interaction.

Usage:
Instantiate the BlazeMomentsPlayerContainerTabs with the desired configuration and delegate, then use the startPlaying(in:containerView:) method to begin playback of moments within the specified view controller and container view. The closePlayer(completion:) method allows for graceful termination of the playback.

📘

Player Container Tabs will notify if any data exists for display.

Player Container Tabs doesn't provide empty state UI display.
App developers should make sure to decide on proper logic for empty state.

BlazeMomentsPlayerContainerTabs

initialize

Initializes a new instance of BlazeMomentsPlayerContainerTabs

public init(tabs: [BlazeMomentsContainerTabItem],
            playerStyle: BlazeMomentsPlayerStyle? = nil,
            playbackConfiguration: BlazeMomentsPlaybackConfiguration? = nil,
            tabsStyle: BlazePlayerTabsStyle? = nil,
            containerTabsDelegate: BlazePlayerContainerTabsDelegate?,
            containerSourceId: String)

Parameters:

  • tabs: Array of tab configurations, each containing its own data source and settings
  • playerStyle: The moments player style configuration applied to all tabs. Defaults to SDK's default style
  • playbackConfiguration: The moments playback configuration applied to all tabs. Controls loop behavior and playback settings. Defaults to SDK's default playback configuration
  • tabsStyle: The visual style configuration for the tabs interface. Defaults to base tabs style
  • containerTabsDelegate: Delegate object for handling container-wide events and interactions
  • containerSourceId: Unique identifier for this container instance. This identifier MUST be unique per instance in the app

Example

let momentsPlayerStyle = BlazeMomentsPlayerStyle.base()
momentsPlayerStyle.buttons.exit.isVisible = false

let tabsStyle = BlazePlayerTabsStyle.base()

var playbackConfiguration = BlazeMomentsPlaybackConfiguration.base()
playbackConfiguration.loopBehavior = .loopAndAdvance(numberOfPlays: 3)

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

let tabsContainer = BlazeMomentsPlayerContainerTabs(
    tabs: tabs,
    playerStyle: momentsPlayerStyle,
    playbackConfiguration: playbackConfiguration,
    tabsStyle: tabsStyle,
    containerTabsDelegate: BlazePlayerContainerTabsDelegate(
        onDataLoadStarted: { params in
            // Handle data load started
        },
        onDataLoadComplete: { params in
            // Handle data load complete
        },
        onTabSelected: { params in
            // Handle tab selection
        }
    ),
    containerSourceId: "unique-container-source-id"
)

BlazeMomentsContainerTabItem

The BlazeMomentsContainerTabItem struct represents a single tab in the container. Each tab can be configured with the following properties:

public struct BlazeMomentsContainerTabItem {
    public let containerId: String
    public let title: String
    public let isVisible: Bool
    public let dataSource: BlazeDataSourceType
    public let icon: BlazePlayerTabItemCustomImageStates?
    public let shouldOrderMomentsByReadStatus: Bool
    public let cachePolicyLevel: BlazeCachePolicyLevel?
    public let momentsAdsConfigType: BlazeMomentsAdsConfigType
}

Properties

containerId

A unique identifier for the tab. Must be unique within the container.

title

The display title of the tab.

dataSource

The data source for the tab's content, built with BlazeDataSourceType.

shouldOrderMomentsByReadStatus

When true, moments are ordered with unread content appearing first. Defaults to true.

cachePolicyLevel

Controls caching behavior for the tab's content. Defaults to nil, which uses the global SDK caching level.

Available values:

  • .Low - Pre-fetches the consequent page only, while a page is playing
  • .Default - Pre-fetches the first visible page after loading, and the consequent page while a page is playing
  • .High - Pre-fetches the first page of the first 3 items after loading, and up to 2 consequent pages while a page is playing
  • .Extreme - Pre-fetches the first page of the first 5 items after loading, and up to 4 consequent pages while a page is playing

momentsAdsConfigType

Configures ad behavior for the tab. Defaults to .firstAvailableAdsConfig.

Available values:

  • .firstAvailableAdsConfig - Uses the primary ad configuration from the app-wide settings
  • .everyXMoments - Ads are displayed after a set number of moments
  • .none - No ads will be displayed

isVisible

Controls tab visibility. When false, the tab is hidden from the UI. Defaults to true.

icon

Optional custom icon for the tab using BlazePlayerTabItemCustomImageStates.

BlazePlayerTabsStyle

The BlazePlayerTabsStyle struct represents the visual style configuration for the tabs interface.

public struct BlazePlayerTabsStyle: Equatable {
    public var padding: NSDirectionalEdgeInsets
    public var gradient: BlazePlayerTabsGradientStyle
    public var icon: BlazePlayerTabItemIconStyle?
    public var selectedTabState: BlazePlayerTabItemStyle
    public var unselectedTabState: BlazePlayerTabItemStyle
    public var activeTabIndicator: BlazePlayerActiveTabIndicatorStyle
    public var isTabTitleVisibleWhenSingleTab: Bool
    public var isTabVisibleWhenEmpty: Bool
}

Use BlazePlayerTabsStyle.base() to obtain the default style, then customize its properties:

var tabsStyle = BlazePlayerTabsStyle.base()
tabsStyle.activeTabIndicator.isVisible = true
tabsStyle.isTabTitleVisibleWhenSingleTab = false

Properties

padding

The padding around the tabs strip.

gradient

The gradient style shown behind the tabs strip.

icon

Optional icon style shown alongside the tab title.

selectedTabState

The style applied to the currently selected tab.

unselectedTabState

The style applied to unselected tabs.

activeTabIndicator

The underline indicator style for the active tab. See BlazePlayerActiveTabIndicatorStyle.

isTabTitleVisibleWhenSingleTab

Controls whether the tab bar is shown when the container has only a single visible tab.

  • false (default) — the tab bar is hidden when there's a single visible tab, and the player is laid out like a standalone player.
  • true — the tab bar is shown even for a single visible tab.

With two or more visible tabs, the tab bar is always shown regardless of this flag.

isTabVisibleWhenEmpty

Controls whether a tab stays visible when it has no content.

  • true (default) — a tab with no content (or a failed data load) stays visible and presents the player's empty or error state.
  • false — such a tab is automatically removed after its content is prepared.

The first tab is always kept regardless of this flag.

BlazePlayerActiveTabIndicatorStyle

The BlazePlayerActiveTabIndicatorStyle struct represents the style configuration for the indicator displayed on the active (selected) tab.

The indicator is opt-in: it is not shown unless isVisible is set to true. The indicator color always matches the selected tab's text color and cannot be configured separately. The indicator width always matches the selected tab title's text width. The indicator is always center-aligned beneath the tab title.

public struct BlazePlayerActiveTabIndicatorStyle: Equatable {
    public var isVisible: Bool
    public var height: CGFloat
}

Properties

isVisible

A flag indicating whether the indicator is shown on the active tab. Defaults to false (no indicator).

height

The height of the underline bar, in points.

Methods

startPlaying

public func startPlaying(in parentViewController: UIViewController, containerView: UIView? = nil)

Starts playing the tabs container in a specific parent view controller. The container will attempt to restore the previously selected tab if available.

Parameters:

  • parentViewController: The parent view controller where tabs should be embedded
  • containerView: Optional specific view to embed in. Defaults to parentViewController.view

closePlayer

public func closePlayer(completion: (() -> Void)? = nil)

Closes the entire tabs container and dismisses all players. This method stops all active players, cleans up resources, and removes the container from its parent.

Parameters:

  • completion: Optional completion handler called when the player is dismissed

upsertTabs

public func upsertTabs(_ tabs: [BlazeMomentsContainerTabItem])

Updates existing tabs or adds new ones based on their container IDs. If a tab with the same containerId exists, it will be replaced; otherwise, it will be added to the end of the tabs list.

Parameters:

  • tabs: Array of tabs to upsert

updateTabsStyle

public func updateTabsStyle(_ tabsStyle: BlazePlayerTabsStyle)

Updates the visual styling of the tabs interface. Changes will be applied immediately to the visible tabs interface.

Parameters:

  • tabsStyle: New tabs style configuration to apply

reloadAllTabs

public func reloadAllTabs()

Reloads the content of all tabs from their configured data sources, including the currently active tab.

Each tab re-fetches its data and updates the displayed content. If the active tab is reloaded, the user will be scrolled to the top of the list.

If a tab's data source fails during reload, that tab retains its previously loaded content and surfaces an error through the standard error reporting mechanism. Other tabs are not affected.

📘

Recommended for use when the user is not actively viewing the tabs component, as the active tab will be reset.

reloadNonActiveTabs

public func reloadNonActiveTabs()

Reloads the content of all tabs except the currently active one.

Each non-active tab re-fetches its data and updates its content. The active tab remains untouched, preserving the user's current viewing experience.

If a tab's data source fails during reload, that tab retains its previously loaded content and surfaces an error through the standard error reporting mechanism. Other tabs are not affected.

reloadTab (by index)

public func reloadTab(at index: Int)

Reloads the content of a specific tab at the given index from its configured data source.

This method re-fetches data for the specified tab and updates its displayed content. If the specified tab is currently active, the user will be scrolled to the top of the list.

If the tab's data source fails during reload, the tab retains its previously loaded content and surfaces an error through the standard error reporting mechanism.

No-op when the index is out of bounds.

Parameters:

  • index: The index of the tab to reload (0-based)

reloadTab (by container ID)

public func reloadTab(containerId: String)

Reloads the content of a specific tab identified by its container ID from its configured data source.

This method re-fetches data for the specified tab and updates its displayed content. If the specified tab is currently active, the user will be scrolled to the top of the list.

If the tab's data source fails during reload, the tab retains its previously loaded content and surfaces an error through the standard error reporting mechanism.

No-op when no tab matches the provided container ID.

Parameters:

  • containerId: The unique container identifier of the tab to reload

Reload Usage Example

// Reload all tabs (e.g. on pull-to-refresh or app foregrounding)
tabsContainer.reloadAllTabs()

// Reload only background tabs while user is watching the active tab
tabsContainer.reloadNonActiveTabs()

// Reload a specific tab by index
tabsContainer.reloadTab(at: 0)

// Reload a specific tab by container ID
tabsContainer.reloadTab(containerId: "unique-tab-id-trending")

updatePlaybackConfiguration

public func updatePlaybackConfiguration(_ configuration: BlazeMomentsPlaybackConfiguration)

Updates the playback configuration for all tabs in the container. Changes will be applied immediately to all existing tab players.

This method allows dynamic modification of playback behavior (such as loop behavior) after container initialization without recreating the container.

Parameters:

  • configuration: New playback configuration to apply

Example:

var newPlaybackConfig = BlazeMomentsPlaybackConfiguration.base()
newPlaybackConfig.loopBehavior = .infiniteLoop

tabsContainer.updatePlaybackConfiguration(newPlaybackConfig)

removeTabs

public func removeTabs(ids: [String])

Removes tabs from the container by their container IDs. The container will automatically update its UI and restart playback with the remaining tabs.

Parameters:

  • ids: Array of container IDs to remove

resumePlayer

public func resumePlayer()

Starts or resumes playback of the currently active player. If no tab is selected, this method has no effect.

pausePlayer

public func pausePlayer()

Pauses the currently active player. This method does not dismiss the player; it simply pauses playback, allowing for later resumption.

blockPlayerInteraction

public func blockPlayerInteraction()

Blocks all player interactions across all tabs. This prevents users from pausing, resuming, or controlling players directly, but allows automatic playback when switching tabs.

unblockPlayerInteraction

public func unblockPlayerInteraction()

Restores player interactions across all tabs. Re-enables user control of players (pause, resume, etc.) but does not automatically activate any player.

blockTabsInteraction

public func blockTabsInteraction()

Blocks tab navigation interactions. Prevents users from tapping on tab buttons to switch tabs or swiping between tabs using page scrolling.

unblockTabsInteraction

public func unblockTabsInteraction()

Restores tab navigation interactions. Re-enables tab button tapping and page scrolling between tabs.

selectTab

public func selectTab(at index: Int, animated: Bool = true)

Selects and activates a tab at the specified index with animation control.

Parameters:

  • index: The index of the tab to select (0-based)
  • animated: Whether to animate the transition (default: true)

prepareTab

public func prepareTab(at index: Int)

Prepares content for a specific tab at the given index. This method pre-loads and caches moments data for the specified tab without starting playback.

Parameters:

  • index: The index of the tab to prepare

prepareAllTabs

public func prepareAllTabs()

Prepares content for all tabs in the container. This method pre-loads and caches moments data for all tabs without starting playback.

BlazePlayerContainerTabsDelegate

BlazePlayerContainerTabsDelegate is a struct that conforms to the BlazePlayerSourceDelegate protocol and provides callback handlers for tabs container interactions. This delegate consolidates all player events from multiple tabs into a single interface, making it easier to handle moments playback across different data sources within one container.

📘

All functions in this struct are optional, the choice of which function to implement is left for app developers.

Available Handlers

public struct BlazePlayerContainerTabsDelegate: BlazePlayerSourceDelegate {
    public var onDataLoadStarted: OnDataLoadStartedHandler?
    public var onDataLoadComplete: OnDataLoadCompleteHandler?
    public var onPlayerDidAppear: OnPlayerDidAppearHandler?
    public var onPlayerDidDismiss: OnPlayerDidDismissHandler?
    public var onTriggerCTA: OnTriggerCTAHandler?
    public var onTriggerPlayerBodyTextLink: OnTriggerPlayerBodyTextLinkHandler?
    public var onPlayerEventTriggered: OnPlayerEventTriggeredHandler?
    public var onTriggerCustomActionButton: OnTriggerCustomActionButtonHandler?
    public var onTabSelected: OnTabSelectedHandler?
}

onTabSelected

Handler signature

public typealias OnTabSelectedHandler = ((playerType: BlazePlayerType, sourceId: String, tabIndex: Int)) -> Void

Called when a tab is selected in the container, either programmatically or through user interaction. Use this to track tab navigation analytics or update external UI elements.

Parameters:

  • playerType: The type of the player
  • sourceId: The combined source identifier in format: <containerSourceId>_<tabId>
  • tabIndex: The index of the selected tab (0-based)

SwiftUI Integration

For SwiftUI integration, use BlazeSwiftUIMomentsPlayerContainerTabsView:

struct ContentView: View {
    let tabsContainer = BlazeMomentsPlayerContainerTabs(
        tabs: [
            BlazeMomentsContainerTabItem(
                containerId: "tab1",
                title: "For You",
                dataSource: BlazeDataSourceType.labels(BlazeWidgetLabel.singleLabel("for_you"))
            ),
            BlazeMomentsContainerTabItem(
                containerId: "tab2",
                title: "Trending",
                dataSource: BlazeDataSourceType.labels(BlazeWidgetLabel.singleLabel("trending"))
            )
        ],
        containerTabsDelegate: nil,
        containerSourceId: "swiftui-tabs-container"
    )
    
    var body: some View {
        BlazeSwiftUIMomentsPlayerContainerTabsView(tabsContainer: tabsContainer)
    }
}

Important: Make sure you pass and hold on to a single instance of BlazeMomentsPlayerContainerTabs per container view created.

Update tabs container

If you need to update the container's tabs or configuration:

  • Update tabs using the upsertTabs method:
let newTabs = [
    BlazeMomentsContainerTabItem(
        containerId: "new-tab-id",
        title: "New Tab",
        dataSource: BlazeDataSourceType.labels(BlazeWidgetLabel.singleLabel("new-label"))
    )
]

tabsContainer.upsertTabs(newTabs)
  • Remove tabs using the removeTabs method:
tabsContainer.removeTabs(ids: ["tab-id-to-remove"])
  • Update tabs styling:
let newTabsStyle = BlazePlayerTabsStyle.base()
// Configure new style...

tabsContainer.updateTabsStyle(newTabsStyle)
  • Update playback configuration:
var newPlaybackConfig = BlazeMomentsPlaybackConfiguration.base()
newPlaybackConfig.loopBehavior = .loopAndAdvance(numberOfPlays: 5)

tabsContainer.updatePlaybackConfiguration(newPlaybackConfig)

Important - when updating tabs, make sure each tab has a unique containerId to avoid conflicts.

BlazeMomentsPlaybackConfiguration

The BlazeMomentsPlaybackConfiguration allows you to control playback behavior for all tabs in the container. This configuration is applied to all tabs when the container is initialized, and can be updated dynamically using the updatePlaybackConfiguration method.

Usage with BlazeMomentsPlayerContainerTabs

Initial Configuration

You can provide a playback configuration when initializing the container:

var playbackConfiguration = BlazeMomentsPlaybackConfiguration.base()
playbackConfiguration.loopBehavior = .loopAndAdvance(numberOfPlays: 3)

let tabsContainer = BlazeMomentsPlayerContainerTabs(
    tabs: tabs,
    playerStyle: playerStyle,
    playbackConfiguration: playbackConfiguration,
    tabsStyle: tabsStyle,
    containerTabsDelegate: delegate,
    containerSourceId: "container-id"
)

If playbackConfiguration is not provided (or set to nil), the container will use the SDK's default playback configuration (Blaze.shared.getDefaultMomentsPlaybackConfiguration()).

Dynamic Updates

You can update the playback configuration at any time after initialization:

// Change loop behavior to infinite loop
var newConfig = BlazeMomentsPlaybackConfiguration.base()
newConfig.loopBehavior = .infiniteLoop
tabsContainer.updatePlaybackConfiguration(newConfig)

// Or change to auto-advance after 5 plays
newConfig.loopBehavior = .loopAndAdvance(numberOfPlays: 5)
tabsContainer.updatePlaybackConfiguration(newConfig)

Changes are applied immediately to all existing tab players.

Configuration Properties

The BlazeMomentsPlaybackConfiguration supports the following properties:

  • loopBehavior: Controls how moments loop and advance to the next moment
    • .infiniteLoop - Moment loops infinitely until user navigates manually
    • .loopAndAdvance(numberOfPlays: Int) - Moment loops a specified number of times, then automatically advances

For more details about BlazeMomentsPlaybackConfiguration, see the BlazeMomentsPlaybackConfiguration documentation.



Did this page help you?