mirror of
https://github.com/StikDebug/StikDebug.git
synced 2026-10-16 12:30:29 +00:00
New Custom Tab View
This commit is contained in:
parent
9ff7de2e5c
commit
b3e7a3073b
1 changed files with 136 additions and 34 deletions
|
|
@ -6,50 +6,152 @@
|
|||
//
|
||||
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
fileprivate struct TabItem: Identifiable, Hashable {
|
||||
let id: Int
|
||||
let title: String
|
||||
let systemImage: String
|
||||
}
|
||||
|
||||
fileprivate struct BlurView: UIViewRepresentable {
|
||||
let style: UIBlurEffect.Style
|
||||
func makeUIView(context: Context) -> UIVisualEffectView {
|
||||
UIVisualEffectView(effect: UIBlurEffect(style: style))
|
||||
}
|
||||
func updateUIView(_ uiView: UIVisualEffectView, context: Context) {}
|
||||
}
|
||||
|
||||
fileprivate struct RoundedCorner: Shape {
|
||||
var radius: CGFloat = .infinity
|
||||
var corners: UIRectCorner = .allCorners
|
||||
func path(in rect: CGRect) -> Path {
|
||||
Path(
|
||||
UIBezierPath(
|
||||
roundedRect: rect,
|
||||
byRoundingCorners: corners,
|
||||
cornerRadii: CGSize(width: radius, height: radius)
|
||||
).cgPath
|
||||
)
|
||||
}
|
||||
}
|
||||
fileprivate extension View {
|
||||
func cornerRadius(_ radius: CGFloat, corners: UIRectCorner) -> some View {
|
||||
clipShape(RoundedCorner(radius: radius, corners: corners))
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate struct CustomTabBar: View {
|
||||
let items: [TabItem]
|
||||
@Binding var selection: Int
|
||||
let accentColor: Color
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
ForEach(items) { item in
|
||||
Spacer()
|
||||
Button(action: { withAnimation { selection = item.id } }) {
|
||||
VStack(spacing: 4) {
|
||||
Image(systemName: item.systemImage)
|
||||
.font(.system(size: 20, weight: .semibold))
|
||||
Text(item.title)
|
||||
.font(.caption)
|
||||
}
|
||||
.foregroundColor(selection == item.id ? accentColor : .secondary)
|
||||
}
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 10)
|
||||
.padding(.horizontal, 12)
|
||||
.background(
|
||||
BlurView(style: .systemMaterial)
|
||||
.ignoresSafeArea(edges: .bottom)
|
||||
)
|
||||
.cornerRadius(16, corners: .allCorners)
|
||||
.shadow(color: Color.black.opacity(0.1), radius: 4, x: 0, y: -2)
|
||||
}
|
||||
}
|
||||
|
||||
struct MainTabView: View {
|
||||
@AppStorage("customAccentColor") private var customAccentColorHex: String = ""
|
||||
@AppStorage("enableAdvancedOptions") private var enableAdvancedOptions = false
|
||||
@AppStorage("enableTesting") private var enableTesting = false
|
||||
|
||||
|
||||
@State private var selection: Int = 0
|
||||
@State private var isTabBarHidden: Bool = false
|
||||
|
||||
private var accentColor: Color {
|
||||
if customAccentColorHex.isEmpty {
|
||||
return .blue
|
||||
} else {
|
||||
return Color(hex: customAccentColorHex) ?? .blue
|
||||
}
|
||||
customAccentColorHex.isEmpty
|
||||
? .blue
|
||||
: Color(hex: customAccentColorHex) ?? .blue
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
TabView {
|
||||
HomeView()
|
||||
.tabItem {
|
||||
Label("Home", systemImage: "house")
|
||||
}
|
||||
ScriptListView()
|
||||
.tabItem {
|
||||
Label("Scripts", systemImage: "scroll")
|
||||
}
|
||||
IPAAppManagerView()
|
||||
.tabItem {
|
||||
Label("Testing", systemImage: "square.grid.2x2")
|
||||
}
|
||||
DeviceInfoView()
|
||||
.tabItem {
|
||||
Label("Info", systemImage: "info.circle.fill")
|
||||
}
|
||||
|
||||
private var tabs: [TabItem] {
|
||||
var items: [TabItem] = [
|
||||
TabItem(id: 0, title: "Home", systemImage: "house"),
|
||||
TabItem(id: 1, title: "Scripts", systemImage: "scroll"),
|
||||
TabItem(id: 2, title: "Testing", systemImage: "square.grid.2x2"),
|
||||
]
|
||||
#if DEBUG
|
||||
LocationSimulatorView(deviceIp: "10.7.0.2")
|
||||
.tabItem {
|
||||
Label("Location", systemImage: "globe.americas")
|
||||
}
|
||||
items += [
|
||||
TabItem(id: 3, title: "Location", systemImage: "globe.americas"),
|
||||
TabItem(id: 4, title: "Info", systemImage: "info.circle.fill"),
|
||||
TabItem(id: 5, title: "Settings", systemImage: "gearshape.fill")
|
||||
]
|
||||
#else
|
||||
items += [
|
||||
TabItem(id: 3, title: "Info", systemImage: "info.circle.fill"),
|
||||
TabItem(id: 4, title: "Settings", systemImage: "gearshape.fill")
|
||||
]
|
||||
#endif
|
||||
SettingsView()
|
||||
.tabItem {
|
||||
Label("Settings", systemImage: "gearshape.fill")
|
||||
return items
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .bottom) {
|
||||
Group {
|
||||
switch selection {
|
||||
case 0: HomeView()
|
||||
case 1: ScriptListView()
|
||||
case 2: IPAAppManagerView()
|
||||
#if DEBUG
|
||||
case 3: LocationSimulatorView(deviceIp: "10.7.0.2")
|
||||
case 4: DeviceInfoView()
|
||||
case 5: SettingsView()
|
||||
#else
|
||||
case 3: DeviceInfoView()
|
||||
case 4: SettingsView()
|
||||
#endif
|
||||
default: HomeView()
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.accentColor(accentColor)
|
||||
.environment(\.accentColor, accentColor)
|
||||
|
||||
CustomTabBar(
|
||||
items: tabs,
|
||||
selection: $selection,
|
||||
accentColor: accentColor
|
||||
)
|
||||
.offset(x: isTabBarHidden ? -UIScreen.main.bounds.width : 0,
|
||||
y: -40)
|
||||
.animation(.spring(response: 0.3, dampingFraction: 0.7),
|
||||
value: isTabBarHidden)
|
||||
}
|
||||
.accentColor(accentColor)
|
||||
.environment(\.accentColor, accentColor)
|
||||
.gesture(
|
||||
DragGesture(minimumDistance: 30, coordinateSpace: .local)
|
||||
.onEnded { value in
|
||||
withAnimation(.spring(response: 0.3, dampingFraction: 0.7)) {
|
||||
if value.translation.width < -30 {
|
||||
isTabBarHidden = true
|
||||
} else if value.translation.width > 30 {
|
||||
isTabBarHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
.edgesIgnoringSafeArea(.bottom)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue