Initial tab bar/sidebar implementation

This commit is contained in:
Shadowfacts 2024-08-19 19:10:31 -04:00
parent a8f6aa6ed7
commit 9891b601a8
3 changed files with 56 additions and 9 deletions

View File

@ -70,9 +70,12 @@ class BaseMainTabBarViewController: UITabBarController {
} }
private func repositionFastSwitcherIndicator() { private func repositionFastSwitcherIndicator() {
guard let myProfileButton = findMyProfileTabBarButton() else { guard let myProfileButton = findMyProfileTabBarButton(),
myProfileButton.window != nil else {
fastSwitcherIndicator?.isHidden = true
return return
} }
fastSwitcherIndicator?.isHidden = false
NSLayoutConstraint.deactivate(fastSwitcherConstraints) NSLayoutConstraint.deactivate(fastSwitcherConstraints)
let isPortrait = view.bounds.width < view.bounds.height let isPortrait = view.bounds.width < view.bounds.height
if traitCollection.horizontalSizeClass == .compact && isPortrait { if traitCollection.horizontalSizeClass == .compact && isPortrait {

View File

@ -18,6 +18,7 @@ class NewMainTabBarViewController: BaseMainTabBarViewController {
mode = .tabSidebar mode = .tabSidebar
delegate = self delegate = self
sidebar.delegate = self
tabBar.isSpringLoaded = true tabBar.isSpringLoaded = true
view.backgroundColor = .appBackground view.backgroundColor = .appBackground
@ -57,13 +58,33 @@ class NewMainTabBarViewController: BaseMainTabBarViewController {
case .myProfile: case .myProfile:
root = MyProfileViewController(mastodonController: mastodonController) root = MyProfileViewController(mastodonController: mastodonController)
} }
return EnhancedNavigationViewController(rootViewController: root) let nav: any NavigationControllerProtocol
if UIDevice.current.userInterfaceIdiom == .phone {
nav = EnhancedNavigationViewController()
} else {
// TODO: need to figure out how to update the navigation controller if the pref changes
switch Preferences.shared.widescreenNavigationMode {
case .stack:
nav = EnhancedNavigationViewController()
case .splitScreen:
nav = SplitNavigationController()
case .multiColumn:
nav = MultiColumnNavigationController()
}
}
nav.viewControllers = [root]
return nav
} }
@objc func handleComposeKeyCommand() { @objc func handleComposeKeyCommand() {
compose(editing: nil) compose(editing: nil)
} }
fileprivate func updateViewControllerSafeAreaInsets(_ vc: MultiColumnNavigationController) {
// When in sidebar mode, for multi column mode, don't leave an inset for the floating tab bar, because it leaves a massive gap.
// The floating tab bar seems to always be 88pt tall, regardless of, e.g., Dynamic Type size.
vc.additionalSafeAreaInsets = UIEdgeInsets(top: sidebar.isHidden ? 0 : -88, left: 0, bottom: 0, right: 0)
}
} }
@available(iOS 18.0, *) @available(iOS 18.0, *)
@ -112,12 +133,12 @@ extension NewMainTabBarViewController: UITabBarControllerDelegate {
func tabBarController(_ tabBarController: UITabBarController, shouldSelectTab tab: UITab) -> Bool { func tabBarController(_ tabBarController: UITabBarController, shouldSelectTab tab: UITab) -> Bool {
if tab.identifier == Tab.compose.rawValue { if tab.identifier == Tab.compose.rawValue {
let currentTab = selectedTab let currentTab = selectedTab
compose(editing: nil) { // returning false for shouldSelectTab doesn't prevent the UITabBar from being updated (FB14857254)
// returning false for shouldSelectTab doesn't prevent the UITabBar from being updated (FB14857254) // but we need it to change to _something_ so that we can change back to the current tab
// but we need it to change to _something_ so that we can change back to the current tab self.selectedTab = tab
self.selectedTab = tab self.selectedTab = currentTab
self.selectedTab = currentTab
} compose(editing: nil)
return false return false
} else if let selectedTab, } else if let selectedTab,
selectedTab == tab, selectedTab == tab,
@ -130,6 +151,24 @@ extension NewMainTabBarViewController: UITabBarControllerDelegate {
return true return true
} }
} }
func tabBarController(_ tabBarController: UITabBarController, didSelectTab newTab: UITab, previousTab: UITab?) {
if let vc = newTab.viewController as? MultiColumnNavigationController {
self.updateViewControllerSafeAreaInsets(vc)
}
}
}
@available(iOS 18.0, *)
extension NewMainTabBarViewController: UITabBarController.Sidebar.Delegate {
func tabBarController(_ tabBarController: UITabBarController, sidebarVisibilityWillChange sidebar: UITabBarController.Sidebar, animator: any UITabBarController.Sidebar.Animating) {
if let vc = selectedViewController as? MultiColumnNavigationController {
animator.addAnimations {
self.updateViewControllerSafeAreaInsets(vc)
vc.view.layoutIfNeeded()
}
}
}
} }
@available(iOS 18.0, *) @available(iOS 18.0, *)

View File

@ -155,7 +155,7 @@ class MultiColumnNavigationController: UIViewController {
if columnFrame.maxX < scrollView.bounds.width - scrollView.adjustedTrailingContentInset { if columnFrame.maxX < scrollView.bounds.width - scrollView.adjustedTrailingContentInset {
offset = -scrollView.adjustedLeadingContentInset offset = -scrollView.adjustedLeadingContentInset
} else { } else {
offset = columnFrame.minX + scrollView.adjustedLeadingContentInset - (scrollView.bounds.width - columnFrame.width) offset = scrollView.contentSize.width - scrollView.bounds.width + scrollView.adjustedTrailingContentInset
} }
scrollView.setContentOffset(CGPoint(x: offset, y: -scrollView.adjustedContentInset.top), animated: animated) scrollView.setContentOffset(CGPoint(x: offset, y: -scrollView.adjustedContentInset.top), animated: animated)
} }
@ -185,6 +185,11 @@ class MultiColumnNavigationController: UIViewController {
} }
animator.startAnimation() animator.startAnimation()
} }
// blergh, overriding private method on UIViewController
@objc func _shouldOverlayTabBar() -> Bool {
false
}
} }
extension MultiColumnNavigationController: NavigationControllerProtocol { extension MultiColumnNavigationController: NavigationControllerProtocol {