简体   繁体   English

Swiftui 如何在 tabview 上方添加视图?

[英]Swiftui how to add a view above a tabview?

The requirement is to display a banner above the tabbar.要求是在标签栏上方显示横幅。 So that the banner does not disappear when the tabs are changed?以便在更改选项卡时横幅不会消失? How can I achieve it?我怎样才能实现它?

在此处输入图像描述

I can think of starting points, to help you see ways to approach this, but I don't think either idea really meets your requirements.我可以想到起点,以帮助您找到解决方法,但我认为这两个想法都不能真正满足您的要求。 It will depend on the details of whether the banner is permanent, where its content comes from, etc.这将取决于横幅是否是永久性的、其内容来自何处等细节。

The first idea:第一个想法:

struct BannerView : View {
    
    var text : String
    
    var body: some View {
        VStack {
            Spacer()
            HStack {
                Spacer()
                Text(text)
                Spacer()
            }.background(Color.orange)
            
        }
    }
}

Then you can include this in a ZStack along with your tabs:然后,您可以将其与选项卡一起包含在ZStack中:

TabView {
    ZStack {
        Text("Tab 1")
        BannerView("BANNER")
    }.tabItem { Text("Home") }
    ZStack {
        Text("Tab 2")
        BannerView("BANNER")
    }.tabItem { Text("History") }
}           

The second idea uses the BannerView from the first idea, but in a slightly cleaner way, still not great:第二个想法使用了第一个想法中的BannerView ,但是以一种更简洁的方式,仍然不是很好:

struct TabWrapperWithOptionalBanner<Content> : View where Content : View {

    var showBanner : Bool
    var content : Content
    
    init(showBanner : Bool, @ViewBuilder content: () -> Content) {
        self.showBanner = showBanner
        self.content = content()
    }
        
    var body: some View {
        ZStack {
            content
            if showBanner {
                BannerView(text: "BANNER")
            }
        }
    }
}

then your ContentView looks like this:那么你的 ContentView 看起来像这样:

TabView {
    TabWrapperWithOptionalBanner(showBanner: showBanner) {
        Text("Tab 1")
    }.tabItem { Text("Home") }
    TabWrapperWithOptionalBanner(showBanner: showBanner) {
        Text("Tab 2")
    }.tabItem { Text("History") }
}

Update Try a pair of TabViews bound to the same State:更新尝试一对绑定到相同 State 的 TabView:

struct BanneredTabView: View {
    @State private var selected = panels.one
    
    var body: some View {
        VStack {
            TabView(selection: $selected) {
                panels.one.label.tag(panels.one)
                panels.two.label.tag(panels.two)
                panels.three.label.tag(panels.three)
            }
            .tabViewStyle(PageTabViewStyle())
            Text("Banner")
                .frame(height: 40, alignment: .top)
            TabView(selection: $selected) {
                ForEach(panels.allCases) { panel in
                    Text("").tabItem {
                        panel.label
                    }
                    .tag(panel)
                }
            }
            .frame(height: 30)
        }
    }
    
    enum panels : Int, CaseIterable, Identifiable {
        case one = 1
        case two = 2
        case three = 3
        
        var label : some View {
            switch self {
            case .one:
                return Label("Tab One", systemImage: "1.circle")
            case .two:
                return Label("Tab Two", systemImage: "2.square")
            case .three:
                return Label("Tab Three", systemImage: "asterisk.circle")
            }
        }
        // so the enum can be identified when enumerated
        var id : Int { self.rawValue }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM