我在按SocialView()上的按钮时尝试切换到另一个选项卡(例如WorkOutView())。但是,我一直在SwiftUI中使用UIKit tabview的包装结构。
包装器:
struct UIKitStyleTabView: View {
var viewControllers: [HostingController<AnyView>]
//@State var switchTab = 0
struct Tab {
var view: AnyView
var barItem: UITabBarItem
init<V: View>(view: V, barItem: UITabBarItem) {
self.view = AnyView(view)
self.barItem = barItem
}
}
init(_ tabs: [Tab]) {
self.viewControllers = tabs.map {
let host = HostingController(rootView: $0.view)
host.tabBarItem = $0.barItem
return host
}
}
var body: some View {
TabBarController(controllers: viewControllers, switchTab: $switchTab)
.edgesIgnoringSafeArea(.all)
}
}
struct TabBarController: UIViewControllerRepresentable {
var controllers: [UIViewController]
@Binding var switchTav: Int
func makeUIViewController(context: Context) -> UITabBarController {
let tabBarController = UITabBarController()
tabBarController.viewControllers = controllers
return tabBarController
}
func updateUIViewController(_ uiViewController: UITabBarController, context: Context) {
//uiViewController.selectedIndex = switchTab
}
}
我这样设置:
struct MainView : View {
//@Binding var switchTab: Int
let tabBarSymbolConfig = UIImage.SymbolConfiguration(scale: .medium)
var body : some View {
UIKitStyleTabView([
UIKitStyleTabView.Tab(view: SocialView(switchTab: $switchTab).accentColor(.white), barItem: UITabBarItem(title: "Social", image: UIImage(systemName: "person.3.fill", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: SearchView().accentColor(.white), barItem: UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: WorkoutsView().accentColor(.white),barItem: UITabBarItem(title: "Workouts", image: UIImage(systemName: "doc.on.clipboard.fill", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: ExercisesView().accentColor(.white), barItem: UITabBarItem(title: "Exercises", image: UIImage(systemName: "sportscourt", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: AccountView().accentColor(.white), barItem: UITabBarItem(title: "Me", image: UIImage(systemName: "person.crop.circle", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
)
], switchTab: $switchTab).accentColor(.navIconColor)
我试图在连接这些视图的所有位置插入一个状态/绑定变量,以便可以在updateUIViewController函数中使用它,但这并没有真正起作用,因为我最终不得不在SceneDelegate中插入一个Binding。 / p>
任何建议如何实现这一目标?
答案 0 :(得分:1)
这是经过纠正和工作的变体(由于缺少许多组件而已被复制,因此需要您适应)。
通过Xcode 11.4 / iOS 13.4测试
完整的模块代码:
struct UIKitStyleTabView: View {
var viewControllers: [UIHostingController<AnyView>]
@Binding var switchTab: Int
struct Tab {
var view: AnyView
var barItem: UITabBarItem
init<V: View>(view: V, barItem: UITabBarItem) {
self.view = AnyView(view)
self.barItem = barItem
}
}
init(_ tabs: [Tab], switchTab: Binding<Int>) {
self.viewControllers = tabs.map {
let host = UIHostingController(rootView: $0.view)
host.tabBarItem = $0.barItem
return host
}
self._switchTab = switchTab
}
var body: some View {
TabBarController(controllers: viewControllers, switchTab: $switchTab)
.edgesIgnoringSafeArea(.all)
}
}
struct TabBarController: UIViewControllerRepresentable {
var controllers: [UIViewController]
@Binding var switchTab: Int
func makeUIViewController(context: Context) -> UITabBarController {
let tabBarController = UITabBarController()
tabBarController.viewControllers = controllers
tabBarController.delegate = context.coordinator
return tabBarController
}
func updateUIViewController(_ uiViewController: UITabBarController, context: Context) {
uiViewController.selectedIndex = switchTab
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, UITabBarControllerDelegate {
let owner: TabBarController
init(_ owner: TabBarController) {
self.owner = owner
}
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
owner.switchTab = tabBarController.selectedIndex
}
}
}
struct TabsMainView : View {
@State var switchTab: Int = 0
let tabBarSymbolConfig = UIImage.SymbolConfiguration(scale: .medium)
var body : some View {
UIKitStyleTabView([
UIKitStyleTabView.Tab(view: SocialView(switchTab: $switchTab).accentColor(.white), barItem: UITabBarItem(title: "Social", image: UIImage(systemName: "person.3.fill", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("SearchView").accentColor(.white), barItem: UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("WorkoutsView").accentColor(.white),barItem: UITabBarItem(title: "Workouts", image: UIImage(systemName: "doc.on.clipboard.fill", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("ExercisesView").accentColor(.white), barItem: UITabBarItem(title: "Exercises", image: UIImage(systemName: "sportscourt", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("AccountView").accentColor(.white), barItem: UITabBarItem(title: "Me", image: UIImage(systemName: "person.crop.circle", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
)
], switchTab: $switchTab)//.accentColor(.navIconColor)
}
}
struct SocialView: View {
@Binding var switchTab: Int
var body: some View {
Button("Go Search") { self.switchTab = 1 }
}
}
struct TabsMainView_Previews: PreviewProvider {
static var previews: some View {
TabsMainView().colorScheme(.dark)
}
}