【发布时间】:2023-02-02 16:52:53
【问题描述】:
我正在尝试在 SwiftUI 中创建自定义 TabView,它也具有 .tabViewStyle(.page()) 功能。
目前我已经完成了 99%,但无法弄清楚如何将所有 TabBarItems 列出。
我正在使用 PreferenceKey,这样我将它们添加到闭包中的顺序就是 TabView 中的顺序。
当我运行它时,选项卡项被添加到数组中,然后被删除,但它似乎不起作用。
我使用枚举作为CaseIterable,将ForEach(tabs) { tab in作为ForEach(TabBarItems.allCases) { tab in使用,但如前所述,我希望栏中的顺序是来自clousure的有机顺序。
容器
struct TabViewContainer<Content : View>: View {
@Binding private var selection: TabBarItem
@State private var tabs: [TabBarItem] = []
var content: Content
init(selection: Binding<TabBarItem>, @ViewBuilder content: () -> Content) {
self._selection = selection
self.content = content()
}
var body: some View {
ZStack(alignment: .bottom) {
TabView(selection: $selection) {
content
}
.tabViewStyle(.page(indexDisplayMode: .never))
tabBarItems()
}
.onPreferenceChange(TabBarItemsPreferenceKey.self) { self.tabs = $0 }
}
private func tabBarItems() -> some View {
HStack(spacing: 10) {
ForEach(tabs) { tab in
Button {
selection = tab
} label: {
tabButton(tab: tab)
}
}
}
.padding(.horizontal)
.frame(maxWidth: .infinity)
.padding(.top, 8)
.background(Color(uiColor: .systemGray6))
}
private func tabButton(tab: TabBarItem) -> some View {
VStack(spacing: 0) {
Image(icon: tab.icon)
.font(.system(size: 16))
.frame(maxWidth: .infinity, minHeight: 28)
Text(tab.title)
.font(.system(size: 10, weight: .medium, design: .rounded))
}
.foregroundColor(selection == tab ? tab.colour : .gray)
}
}
首选项键/修饰符
struct TabBarItemsPreferenceKey: PreferenceKey {
static var defaultValue: [TabBarItem] = []
static func reduce(value: inout [TabBarItem], nextValue: () -> [TabBarItem]) {
value += nextValue()
}
}
struct TabBarItemViewModifier: ViewModifier {
let tab: TabBarItem
func body(content: Content) -> some View {
content.preference(key: TabBarItemsPreferenceKey.self, value: [tab])
}
}
extension View {
func tabBarItem(_ tab: TabBarItem) -> some View {
modifier(TabBarItemViewModifier(tab: tab))
}
}
演示视图
struct TabSelectionView: View {
@State private var selection: TabBarItem = .itinerary
var body: some View {
TabViewContainer(selection: $selection) {
PhraseView()
.tabBarItem(.phrases)
ItineraryView()
.tabBarItem(.itinerary)
BudgetView()
.tabBarItem(.budget)
BookingView()
.tabBarItem(.bookings)
PackingListView()
.tabBarItem(.packing)
}
}
}
| Intended | Current |
|---|---|
【问题讨论】:
标签: ios swift swiftui swiftui-tabview