Initial tab bar/sidebar implementation
This commit is contained in:
parent
a8f6aa6ed7
commit
9891b601a8
|
@ -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 {
|
||||||
|
|
|
@ -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, *)
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue