在 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 视图的主要内容,如果未能解决你的问题,请参考以下文章
如何从 webkit swiftUI 中的文本字段中搜索自定义文本
我们如何在 SwiftUI 中制作自定义 GeometryReader?
SwiftUI 自定义 List 不能在 ForEach 中使用 Binding
安装了 FB 应用程序的 SwiftUI 自定义 Facebook 登录