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.canGoBackto conditionally show a back button.