Skip to main content

Embedded Integration

Embed the channel within your app's existing UI — alongside custom headers, footers, or inside a TabView.

With Custom Header

A common pattern: your own navigation bar above the channel.

import SwiftUI
import BBChannelSwiftUI

struct EmbeddedChannelView: View {
@StateObject private var viewModel = BBChannelViewModel()

var body: some View {
VStack(spacing: 0) {
// Custom header
HStack {
if viewModel.canGoBack {
Button("← Back") { viewModel.goBack() }
}
Spacer()
Text("Videos").font(.headline).foregroundColor(.white)
Spacer()
Button("Home") { viewModel.navigateTo(page: "main") }
}
.padding()
.background(Color(white: 0.1))
.foregroundColor(.white)

// Channel fills remaining space
BBChannelView(
channelUrl: "https://demo.bbvms.com/ch/channel_name.json",
viewModel: viewModel,
callbacks: BBChannelCallbacks()
)

// Footer
Text("Powered by Blue Billywig")
.font(.caption).foregroundColor(.gray)
.padding(8)
.frame(maxWidth: .infinity)
.background(Color(white: 0.1))
}
.background(Color.black)
}
}

Dynamic Height

If the channel doesn't fill the entire screen, give it a fixed height:

VStack {
Text("Featured Content")
.font(.title).foregroundColor(.white)

BBChannelView(
channelUrl: "https://demo.bbvms.com/ch/channel_name.json",
viewModel: viewModel,
callbacks: callbacks
)
.frame(height: 400)

Text("Other Content")
.foregroundColor(.white)
}
warning

A fixed-height channel is scrollable internally. The channel handles its own scrolling, so avoid nesting it inside a ScrollView.

TabView Integration

import SwiftUI
import BBChannelSwiftUI

struct MainTabView: View {
var body: some View {
TabView {
HomeView()
.tabItem { Label("Home", systemImage: "house") }

VideoTabView()
.tabItem { Label("Videos", systemImage: "play.rectangle") }

ProfileView()
.tabItem { Label("Profile", systemImage: "person") }
}
}
}

struct VideoTabView: View {
@StateObject private var viewModel = BBChannelViewModel()

var body: some View {
BBChannelView(
channelUrl: "https://demo.bbvms.com/ch/channel_name.json",
viewModel: viewModel,
callbacks: BBChannelCallbacks()
)
}
}

Key Points

  • When you provide your own header, the channel doesn't need to handle safe areas — your parent view does.
  • The channel handles its own scrolling; don't nest it in a ScrollView.
  • Use viewModel.canGoBack to conditionally show a back button.