【问题标题】:Custom Menu/Tab bar in SwiftUISwiftUI 中的自定义菜单/标签栏
【发布时间】:2022-11-28 09:36:42
【问题描述】:

我想制作这样的标签栏,但不知道从哪里开始。请帮助我,我是新手!

它导航到不同的视图。

【问题讨论】:

  • 这很可能可以通过 SwiftUI Picker 来实现。
  • 如果你搜索“custom tab bar swiftui”,那里有很多教程
  • 我确实搜索过它但找不到所需的样式选项卡栏或选择器

标签: swift uitableview swiftui


【解决方案1】:

这是一个非常实用的版本。这可以做得更好,以进一步反映 SwiftUI 的 TabBar 界面。如果您遇到任何问题,请告诉我。

protocol TopTab: RawRepresentable, Identifiable, CaseIterable, Hashable where AllCases == Array<Self> {
    var title: String { get }
}

struct TabBackground: Shape {
    var cornerRadius: CGFloat = 8
    func path(in rect: CGRect) -> Path {
        var path = Path()
        path.move(to: CGPoint(x: .zero + cornerRadius, y: .zero))
        path.addLine(to: CGPoint(x: rect.width - cornerRadius, y: .zero))
        path.addQuadCurve(to: CGPoint(x: rect.width, y: .zero + cornerRadius), control: CGPoint(x: rect.width, y: .zero))
        path.addLine(to: CGPoint(x: rect.width, y: rect.height - cornerRadius))
        path.addQuadCurve(to: CGPoint(x: rect.width + cornerRadius, y: rect.height), control: CGPoint(x: rect.width, y: rect.height))
        path.addLine(to: CGPoint(x: .zero - cornerRadius, y: rect.height))
        path.addQuadCurve(to: CGPoint(x: .zero, y: rect.height - cornerRadius), control: CGPoint(x: .zero, y: rect.height))
        path.addLine(to: CGPoint(x: .zero, y: cornerRadius))
        path.addQuadCurve(to: CGPoint(x: .zero + cornerRadius, y: .zero), control: .zero)
        return path
    }
}

struct TopScrollingTabBarPicker<Tab: TopTab>: View {
    @Binding var selection: Tab
    
    var body: some View {
        
        ScrollView(.horizontal, showsIndicators: false) {
            LazyHStack {
                ForEach(Tab.allCases) { tab in
                    Group {
                        if tab == selection {
                            Text(tab.title)
                                .bold()
                                .foregroundColor(.accentColor)
                                .padding(12)
                                .background {
                                    TabBackground(cornerRadius: 16)
                                        .fill(Color.white)
                                }
                        } else {
                            Text(tab.title)
                                .padding(4)
                                .foregroundColor(.white)
                        }
                    }
                    .tag(tab)
                    .onTapGesture {
                        selection = tab
                    }
                }
            }
            .padding(.horizontal, 10)
        }
        .background(Color.accentColor)
    }
}

struct TopScrollingTabBar<Tab: TopTab, Content: View>: View {
    var alignment: HorizontalAlignment = .leading
    @Binding var selection: Tab
    @ViewBuilder var content: (_ tab: Tab) -> Content
    
    var body: some View {
        GeometryReader { geometry in
            VStack(alignment: alignment) {
                TopScrollingTabBarPicker(selection: $selection)
                    .frame(height: 44)
                ZStack {
                    Color(.systemBackground)
                        .ignoresSafeArea()
                    self.content(selection)
                        .transition(.asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing)))
                }
            }
        }
    }
}

用法:

enum PreviewTab: String, TopTab {
    case saved
    case booked
    case pending
    case confirmed
    case archived
    
    var id: String {
        rawValue
    }
    
    var title: String {
        switch self {
        case .saved:
            return "Saved"
        case .booked:
            return "Booked"
        case .pending:
            return "Pending"
        case .confirmed:
            return "Confirmed"
        case .archived:
            return "Archived"
        }
    }
}

struct ContentView: View {
    
    @State var selection: PreviewTab = .saved
    
    var body: some View {
        TopScrollingTabBar(selection: $selection.animation()) { tab in
            // For demo purposes
            List {
                Text(tab.title)
                    .bold()
                    .font(.largeTitle)
                Text("Something that is (tab.title)")
            }
            .listStyle(.plain)
            
            // In a full app I'd switch on the Tab enum and generate the appropriate view.
//            switch tab {
//            case .saved:
//                SavedThings()
//            case .booked:
//                ...etc
//            }
        }
    }
}

希望这可以帮助! <3

【讨论】:

    猜你喜欢
    • 2021-04-14
    • 2019-05-21
    • 2010-10-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    相关资源
    最近更新 更多