在 SwiftUI 中构建一个自定义的类 TabView 视图
Posted
技术标签:
【中文标题】在 SwiftUI 中构建一个自定义的类 TabView 视图【英文标题】:Building a custom TabView-like view in SwiftUI 【发布时间】: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。我可以让滚动视图显示正常,但不能显示其内容。你找到解决办法了吗? 好的,我发现我的问题和你的有点不同。但我和你一起玩,找到了答案。我会把它贴在下面:-) 【参考方案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
期望Content
在tabs
中的每个元组中都是相同的类型。如果用户想要比单个Text
更复杂的选项卡,我不确定这是否会编译。以上是关于在 SwiftUI 中构建一个自定义的类 TabView 视图的主要内容,如果未能解决你的问题,请参考以下文章