Я использую настраиваемое представление вкладок, чтобы отображать 6 вкладок в представлении вкладок. Их количество ограничено только 5, поэтому, если вы добавите 6, будет создан раздел «Дополнительно», а 5-я и 6-я вкладки отобразятся в представлении навигации. Когда вы просматриваете 5-ю и 6-ю вкладки, сверху отображается задняя панель навигации с надписью «Еще». У меня есть просмотр вкладок, чтобы отображать все 6 вкладок без опции «еще», но когда я просматриваю 5-ю и 6-ю вкладки, сверху все равно отображается панель навигации с кнопкой «Еще» назад. X реализовал это с помощью 6-х вкладок без дополнительной панели навигации на 5-6 вкладках, так что это, безусловно, возможно.
В идеале я пытаюсь скрыть панель навигации «Еще» из первого представления и сохранить панель навигации фактического представления.
я пытался
View6()
.tag(Tab.home5)
.navigationBarTitle("")
.navigationBarBackButtonHidden(true)
.navigationBarHidden(true)
Просмотр вкладок
VStack(spacing: 0){
TabView(selection: $currentTab) {
View1()
.tag(Tab.home1)
View2()
.tag(Tab.home2)
View3()
.tag(Tab.home3)
View4()
.tag(Tab.home4)
View5()
.tag(Tab.home5)
View6()
.tag(Tab.home6)
}
TabBar()
.toolbar(.hidden, for: .tabBar)
}
Конструктор пользовательских вкладок (показывает все 6 вкладок вместо дополнительного раздела на 5-й вкладке)
@ViewBuilder
func TabBar()->some View{
HStack(spacing: 0){
ForEach(Icons){icon in
let tabColor: SwiftUI.Color = currentTab == icon.tabIcon ? (scheme == .dark ? .white : .black) : .gray.opacity(0.6)
ResizableIconView(IconView: icon.View,color: tabColor)
.aspectRatio(contentMode: .fit)
.frame(width: 30, height: 30)
.frame(maxWidth: .infinity)
.contentShape(Rectangle())
}
}
}
.padding(.horizontal)
.padding(.vertical,10)
.background {
(scheme == .dark ? Color.black : Color.white)
.ignoresSafeArea()
}
}
Когда я просматриваю 5-ю и 6-ю вкладки, отображается дополнительная навигация, как показано ниже: еще панель навигации
Я попытался установить для NavigationBarBackButtonHidden значение true, но это не сработало. Я также пробовал скрыть панель навигации глобально, но при этом удаляются все панели навигации со всех вкладок.
extension UINavigationController {
open override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
navigationBar.isHidden = true
}
}
Я думаю, что решение связано с UIKit
Да, ответ в основном UIKit. Вы должны обернуть UITabBarController
и установить для него moreNavigationController.isNavigationBarHidden
значение true.
Я объединил этот ответ , который показывает простую оболочку вокруг UITabBarController
, с этим ответом о правильном выборе времени для установки isNavigationBarHidden
:
class CustomTabBarController: UITabBarController, UINavigationControllerDelegate {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
moreNavigationController.delegate = self
}
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
// hide the nav bar here:
navigationController.isNavigationBarHidden = true
}
}
struct TabBarController: UIViewControllerRepresentable {
var controllers: [UIViewController]
@Binding var switchTab: Int
func makeUIViewController(context: Context) -> CustomTabBarController {
let tabBarController = CustomTabBarController()
tabBarController.tabBar.isHidden = true // hide the tab bar here
tabBarController.viewControllers = controllers
tabBarController.delegate = context.coordinator
return tabBarController
}
func updateUIViewController(_ uiViewController: CustomTabBarController, 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
}
}
}
@MainActor
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 ContentView : View {
@State var switchTab: Int = 0
let tabBarSymbolConfig = UIImage.SymbolConfiguration(scale: .medium)
var body : some View {
UIKitStyleTabView([
UIKitStyleTabView.Tab(view: Button("Go to tab 6") { self.switchTab = 5 }, barItem: UITabBarItem(title: "Social", image: UIImage(systemName: "person.3.fill", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("SearchView"), barItem: UITabBarItem(title: "Search", image: UIImage(systemName: "magnifyingglass", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("WorkoutsView"),barItem: UITabBarItem(title: "Workouts", image: UIImage(systemName: "doc.on.clipboard.fill", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("ExercisesView"), barItem: UITabBarItem(title: "Exercises", image: UIImage(systemName: "sportscourt", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("AccountView"), barItem: UITabBarItem(title: "Me", image: UIImage(systemName: "person.crop.circle", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
), UIKitStyleTabView.Tab(view: Text("SomeOtherView"), barItem: UITabBarItem(title: "Other", image: UIImage(systemName: "person.crop.circle", withConfiguration: tabBarSymbolConfig)!.withBaselineOffset(fromBottom: 4.5), selectedImage: nil)
)
], switchTab: $switchTab)
}
}
Вы также можете использовать SwiftUI Introspect, чтобы напрямую получить UITabBarController
от TabView
, но он может анализировать только указанные вами версии, поэтому он вообще не ориентирован на будущее.
TabView(selection: $tab) {
ForEach(0..<7) { i in
Text("Tab \(i)").tabItem { Text("\(i)") }
.toolbar(.hidden, for: .tabBar)
}
}
.introspect(.tabView, on: .iOS(.v13, .v14, .v15, .v16, .v17)) { tabView in
tabView.moreNavigationController.isNavigationBarHidden = true
}
@URihal Вы можете использовать SwiftUI Introspect, чтобы получить UITabBarController
, и, возможно, вы сможете сделать с этим что-то подобное. Но это не перспектива на будущее. При использовании SwiftUI-Introspect вы должны указать версии iOS, которые вы хотите проанализировать, чтобы она перестала работать с более новыми версиями, если только SwiftUI Introspect не выпустит новую версию, и вы не обновите свое приложение, а пользователь не установит обновление.
Мне нравится подход Introspect. У меня это работает, но оно скрывает панель навигации представления, а не панель навигации «Дополнительно». Знаете ли вы, как это изменить? View6() .tag(Tab.home6) .introspect(.navigationView(style: .stack), on: .iOS(.v17)) { NavigationController в NavigationController.isNavigationBarHidden = true }
@URihal Посмотрите редактирование. Вам нужно проанализировать .tabView
и получить moreNavigationController
.
Дополнительный вопрос: я впервые включил собственное представление вкладок. Когда я выполняю поиск на вкладке поиска или когда при вводе текста появляется экранная клавиатура, панель вкладок перемещается над клавиатурой. Как лучше всего скрыть пользовательскую вкладку при поиске или вводе текста? (вместо того, чтобы проверять, выполняется ли поиск или набирать текст, а затем передавать $showtab bool через вкладку в представление и изменять его там, могу ли я проверить, включена ли экранная клавиатура, и если да, то отключить панель вкладок глобально?)
@URihal А как насчет .ignoresSafeArea(.keyboard)
на внешней стороне VStack
? Это также может сработать, если вы поместите его на саму панель вкладок, но я не уверен. Я бы посоветовал опубликовать это отдельно, если вы все еще застряли.
Оно работает! Великолепно! Хорошего дня, сэр!
Спасибо! Есть ли способ сохранить текущую панель вкладок и написать расширение UIKit, чтобы просто скрывать первую панель навигации, когда я перехожу на 5-ю и 6-ю вкладки?