Моя цель — сделать так, чтобы BottomNavigationBar влиял только на нижнюю часть экрана, не мешая строка состояния или полноэкранное отображение главного экрана.
BottomNavigationBar.swift
Код: Выделить всё
import SwiftUI
struct BottomNavigationBar: View {
@State private var selectedTab: Int
@State private var selectedRole: UserRole
init(initialRole: UserRole = .maker) {
_selectedRole = State(initialValue: initialRole)
_selectedTab = State(initialValue: 0)
}
var body: some View {
VStack(spacing: 0) {
TabView(selection: $selectedTab) {
roleBasedHomeView(for: selectedTab)
.tag(0)
// Task View
TaskView()
.tag(1)
// Token View
TokenView()
.tag(2)
// Dashboard View
Dashboard()
.tag(3)
// Profile View
Profile()
.tag(4)
}
.tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
HStack {
BottomNavItem(icon: "house", title: "Home", isSelected: selectedTab == 0) {
selectedTab = 0
}
BottomNavItem(icon: "list.bullet", title: "Task", isSelected: selectedTab == 1) {
selectedTab = 1
}
BottomNavItem(icon: "key.fill", title: "Token", isSelected: selectedTab == 2) {
selectedTab = 2
}
BottomNavItem(icon: "chart.bar", title: "Dashboard", isSelected: selectedTab == 3) {
selectedTab = 3
}
BottomNavItem(icon: "person", title: "Profile", isSelected: selectedTab == 4) {
selectedTab = 4
}
}
.padding()
.background(Color.white)
.shadow(color: Color.gray.opacity(0.2), radius: 5, x: 0, y: -2)
}
.edgesIgnoringSafeArea(.bottom)
.statusBar(hidden: true)
}
@ViewBuilder
private func roleBasedHomeView(for tab: Int) -> some View {
switch tab {
case 0:
switch selectedRole {
case .maker:
Home()
case .approver:
HomeAR(role: .approver)
case .releaser:
HomeAR(role: .releaser)
case .approverReleaser:
HomeAR(role: .approverReleaser)
case .makerApprover:
HomeAR(role: .makerApprover)
case .makerApproverReleaserSME:
HomeAR(role: .makerApproverReleaserSME)
case .sysAdmin:
HomeSysAdmin()
default:
WelcomeView()
}
case 1:
TaskView()
case 2:
TokenView()
case 3:
Dashboard()
case 4:
Profile()
default:
WelcomeView()
}
}
}
struct BottomNavItem: View {
var icon: String
var title: String
var isSelected: Bool
var action: () -> Void
var body: some View {
Button(action: action) {
VStack(spacing: 4) {
Image(systemName: icon)
.font(.system(size: 24))
.foregroundColor(isSelected ? Color(hex: "#1E8F7D") : .gray)
Text(title)
.font(.caption)
.foregroundColor(isSelected ? Color(hex: "#1E8F7D") : .gray)
}
.frame(maxWidth: .infinity)
}
}
}
Код: Выделить всё
import SwiftUI
struct Home: View {
@State private var selectedTab: Int = 0
@State private var selectedRole: UserRole = .maker
@State private var showStickyHeader = false
@State private var isHidden = true
@State private var selectedCompany: String = "PT Pertamina Tbk"
@State private var showDropdown = false
let companies = ["PT Pertamina Tbk", "PLN", "PT Timbul Tenggelam"]
var body: some View {
ZStack(alignment: .top) {
Color.primary
.ignoresSafeArea(edges: .all)
.frame(maxWidth: .infinity, maxHeight: .infinity)
ScrollView(showsIndicators: false) {
ZStack(alignment: .top) {
VStack(spacing: 0) {
Color.primary
.frame(height: 250)
.overlay(
Image("pattern_bg_transparent")
.resizable()
.scaledToFill()
.frame(height: 400)
.opacity(0.8)
.clipped()
.ignoresSafeArea(.all)
)
}
.overlay(
GeometryReader { proxy in
Color.clear
.preference(key: ScrollOffsetPreferenceKey.self, value: proxy.frame(in: .global).minY)
}
)
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { offset in
withAnimation(.spring(response: 1.2, dampingFraction: 0.7, blendDuration: 0.8).delay(0.8)) {
showStickyHeader = offset < -50
}
}
// Main contents
VStack(spacing: 16) {
VStack(spacing: 2) {
HStack {
Text("Fredrick Pardosi")
.font(.system(size: 20, weight: .bold))
.foregroundColor(.white)
Spacer()
HStack(spacing: 4) {
Image(systemName: "building.2")
.foregroundColor(.white)
Image(systemName: showDropdown ? "chevron.up" : "chevron.down")
.foregroundColor(.white)
}
.padding(.horizontal, 8)
.padding(.vertical, 6)
.background(RoundedRectangle(cornerRadius: 12).fill(Color.white.opacity(0.2)))
.onTapGesture {
withAnimation {
showDropdown.toggle()
}
}
Image(systemName: "bell")
.foregroundColor(.white)
.padding(8)
.background(Circle().fill(Color.white.opacity(0.2)))
}
.padding(.horizontal, 16)
HStack {
Text("Maker")
.font(.system(size: 14, weight: .medium))
.foregroundColor(.white)
.padding(4)
Spacer()
}
.padding(.horizontal, 16)
}
VStack(spacing: 16) {
TotalBalance(isHidden: $isHidden)
.padding(.top, 8)
DepositLoanView(isHidden: $isHidden)
VStack(alignment: .leading, spacing: 16) {
PendingTaskView(pending: 52, rejected: 1100, executed: 983, title: "Status Transaksi")
ServiceSlider(title: "Status Transaksi by Service")
FeaturedMenu()
}
}
}
}
.background(Color(UIColor.systemGray6).ignoresSafeArea())
}
.refreshable {
refreshContent()
}
if showStickyHeader {
StickyHeader()
.transition(.move(edge: .top))
}
}
.navigationBarBackButtonHidden(true)
}
private func refreshContent() {
print("Content refreshed!")
}
}
[img]https://i .sstatic.net/GP1xqW1Q.png[/img]
Home.swift

Проблема
При прямом переходе на главный экран цвет фона и изображение идеально доходят до строки состояния. Однако доступ к главной странице через BottomNavigationBar предотвращает распространение фона на строку состояния.
Посмотрите разницу между двумя изображениями выше.
Я хочу макет должен выглядеть точно так же, как в Home.swift
Как я могу гарантировать, что BottomNavigationBar не мешает полноэкранному поведению Home, чтобы Home мог дойти до статус bar?
Мы будем очень признательны за любые предложения или рекомендации по правильной настройке BottomNavigationBar или Home. Спасибо!
Подробнее здесь: https://stackoverflow.com/questions/791 ... ow-to-prev