【问题标题】:Building a custom TabView-like view in SwiftUI在 SwiftUI 中构建一个自定义的类 TabView 视图
【发布时间】:2019-10-22 22:52:13
【问题描述】:

我一直在尝试为 macOS 构建一个工具栏-tabview 组件,它可以与子视图组成,就像下面的 TabView 一样:

struct ContentView: View {    
    var body: some View {
        TabView {
            Text("First View")
                .tabItem {
                    Image(name: "NSUserAccounts")
                    Text("First")
                }.tag(0)
            Text("Second View")
                .tabItem {
                    Image(name: "NSUserAccounts")
                    Text("Second")
                }.tag(1)
        }
    }
} 

目前我有这样的事情:

struct ToolbarTabView<Content>: NSViewControllerRepresentable where Content: View {

    let content: () -> Content

    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content
    }

    func makeNSViewController(context: NSViewControllerRepresentableContext<ToolbarTabView>) -> NSTabViewController {
        let vc = NSTabViewController()
        vc.tabStyle = .toolbar


        for item in self.content() as! something? {
            let t = NSTabViewItem(viewController: NSHostingController(rootView: item))
            t.image = item.image
            t.label = item.label
            t.identifier = item.identifier
            vc.addTabViewItem(t)
        }

        return vc
    }

    func updateNSViewController(_ nsViewController: NSTabViewController, context: NSViewControllerRepresentableContext<ToolbarTabView>) {
    }

    typealias NSViewControllerType = NSTabViewController


}

使用 SwiftUI 可以实现这样的事情吗? TabView 内容如何被投射并用于获取 Image 和 Label 信息?

【问题讨论】:

  • 我正在尝试用 NSScrollView 做类似的事情。我试过这样的代码,也试过使用 NSViewRepresentable/NSHostingView。我可以让滚动视图显示正常,但不能显示其内容。你找到解决办法了吗?
  • 好的,我发现我的问题和你的有点不同。但我和你一起玩,找到了答案。我会把它贴在下面:-)

标签: ios swift macos swiftui


【解决方案1】:

除了将内容传递给您的 ToolbarTabView,您还可以让它接受一个还包含其他值的数组。试试这样的:

struct ToolbarTabView<Content>: NSViewControllerRepresentable where Content: View {

    let tabs: [(imageName: String, label: String, identifier: Int, content: () -> Content)]

    init(tabs: [(imageName: String, label: String, identifier: Int, content: () -> Content)]) {
        self.tabs = tabs
    }

    func makeNSViewController(context: NSViewControllerRepresentableContext<ToolbarTabView>) -> NSTabViewController {
        let vc = NSTabViewController()
        vc.tabStyle = .toolbar


        for item in tabs {
            let t = NSTabViewItem(viewController: NSHostingController(rootView: item.content()))
            //t.image = item.image
            t.label = item.label
            t.identifier = item.identifier  // this causes an "unrecognized selector" error, but maybe I'm passing a bad value for this, I'm not sure what it expects
            vc.addTabViewItem(t)
        }

        return vc
    }

    func updateNSViewController(_ nsViewController: NSTabViewController, context: NSViewControllerRepresentableContext<ToolbarTabView>) {
    }

    typealias NSViewControllerType = NSTabViewController


}

struct ToolbarTabView_Previews: PreviewProvider {
    static var previews: some View {
        ToolbarTabView(tabs: [
            (
                imageName: "My Image",
                label: "tab1",
                identifier: 0,
                content: {
                    Text("testing")
                }
            )
        ])
    }
}

【讨论】:

  • 我正在做类似的事情。我看到的问题是您的ToolbarTabView 期望Contenttabs 中的每个元组中都是相同的类型。如果用户想要比单个Text 更复杂的选项卡,我不确定这是否会编译。
猜你喜欢
  • 2022-01-21
  • 2021-03-08
  • 2021-09-12
  • 1970-01-01
  • 2020-11-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多