forked from shadowfacts/Tusker
Use browser-style navigation bars on iPad
This commit is contained in:
parent
f702df2f15
commit
08b7cf013b
|
@ -88,6 +88,7 @@
|
||||||
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */; };
|
D63661C02381C144004B9E16 /* PreferencesNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */; };
|
||||||
D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = D6370B9A24421FF30092A7FF /* Tusker.xcdatamodeld */; };
|
D6370B9C24421FF30092A7FF /* Tusker.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = D6370B9A24421FF30092A7FF /* Tusker.xcdatamodeld */; };
|
||||||
D63A8D0B2561C27F00D9DFFF /* ProfileStatusesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63A8D0A2561C27F00D9DFFF /* ProfileStatusesViewController.swift */; };
|
D63A8D0B2561C27F00D9DFFF /* ProfileStatusesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63A8D0A2561C27F00D9DFFF /* ProfileStatusesViewController.swift */; };
|
||||||
|
D63D8DF42850FE7A008D95E1 /* ViewTags.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63D8DF32850FE7A008D95E1 /* ViewTags.swift */; };
|
||||||
D63F9C6E241D2D85004C03CF /* CompositionAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63F9C6D241D2D85004C03CF /* CompositionAttachment.swift */; };
|
D63F9C6E241D2D85004C03CF /* CompositionAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D63F9C6D241D2D85004C03CF /* CompositionAttachment.swift */; };
|
||||||
D6403CC224A6B72D00E81C55 /* VisualEffectImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6403CC124A6B72D00E81C55 /* VisualEffectImageButton.swift */; };
|
D6403CC224A6B72D00E81C55 /* VisualEffectImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6403CC124A6B72D00E81C55 /* VisualEffectImageButton.swift */; };
|
||||||
D640D76922BAF5E6004FBE69 /* DomainBlocks.plist in Resources */ = {isa = PBXBuildFile; fileRef = D640D76822BAF5E6004FBE69 /* DomainBlocks.plist */; };
|
D640D76922BAF5E6004FBE69 /* DomainBlocks.plist in Resources */ = {isa = PBXBuildFile; fileRef = D640D76822BAF5E6004FBE69 /* DomainBlocks.plist */; };
|
||||||
|
@ -434,6 +435,7 @@
|
||||||
D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesNavigationController.swift; sourceTree = "<group>"; };
|
D63661BF2381C144004B9E16 /* PreferencesNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesNavigationController.swift; sourceTree = "<group>"; };
|
||||||
D6370B9B24421FF30092A7FF /* Tusker.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Tusker.xcdatamodel; sourceTree = "<group>"; };
|
D6370B9B24421FF30092A7FF /* Tusker.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Tusker.xcdatamodel; sourceTree = "<group>"; };
|
||||||
D63A8D0A2561C27F00D9DFFF /* ProfileStatusesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileStatusesViewController.swift; sourceTree = "<group>"; };
|
D63A8D0A2561C27F00D9DFFF /* ProfileStatusesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileStatusesViewController.swift; sourceTree = "<group>"; };
|
||||||
|
D63D8DF32850FE7A008D95E1 /* ViewTags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewTags.swift; sourceTree = "<group>"; };
|
||||||
D63F9C6D241D2D85004C03CF /* CompositionAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionAttachment.swift; sourceTree = "<group>"; };
|
D63F9C6D241D2D85004C03CF /* CompositionAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionAttachment.swift; sourceTree = "<group>"; };
|
||||||
D6403CC124A6B72D00E81C55 /* VisualEffectImageButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualEffectImageButton.swift; sourceTree = "<group>"; };
|
D6403CC124A6B72D00E81C55 /* VisualEffectImageButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisualEffectImageButton.swift; sourceTree = "<group>"; };
|
||||||
D640D76822BAF5E6004FBE69 /* DomainBlocks.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = DomainBlocks.plist; sourceTree = "<group>"; };
|
D640D76822BAF5E6004FBE69 /* DomainBlocks.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = DomainBlocks.plist; sourceTree = "<group>"; };
|
||||||
|
@ -1372,6 +1374,7 @@
|
||||||
D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */,
|
D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */,
|
||||||
D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */,
|
D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */,
|
||||||
D62E9988279DB2D100C26176 /* InstanceFeatures.swift */,
|
D62E9988279DB2D100C26176 /* InstanceFeatures.swift */,
|
||||||
|
D63D8DF32850FE7A008D95E1 /* ViewTags.swift */,
|
||||||
D6D4DDD6212518A200E1C4BB /* Assets.xcassets */,
|
D6D4DDD6212518A200E1C4BB /* Assets.xcassets */,
|
||||||
D6AEBB3F2321640F00E5038B /* Activities */,
|
D6AEBB3F2321640F00E5038B /* Activities */,
|
||||||
D6F1F84E2193B9BE00F5FE67 /* Caching */,
|
D6F1F84E2193B9BE00F5FE67 /* Caching */,
|
||||||
|
@ -1821,6 +1824,7 @@
|
||||||
D681E4D5246E2BC30053414F /* UnmuteConversationActivity.swift in Sources */,
|
D681E4D5246E2BC30053414F /* UnmuteConversationActivity.swift in Sources */,
|
||||||
D6B4A4FF2506B81A000C81C1 /* AccountDisplayNameLabel.swift in Sources */,
|
D6B4A4FF2506B81A000C81C1 /* AccountDisplayNameLabel.swift in Sources */,
|
||||||
D6C143E025354E34007DC240 /* EmojiPickerCollectionViewController.swift in Sources */,
|
D6C143E025354E34007DC240 /* EmojiPickerCollectionViewController.swift in Sources */,
|
||||||
|
D63D8DF42850FE7A008D95E1 /* ViewTags.swift in Sources */,
|
||||||
D6B053A623BD2D0C00A066FA /* AssetCollectionViewController.swift in Sources */,
|
D6B053A623BD2D0C00A066FA /* AssetCollectionViewController.swift in Sources */,
|
||||||
D67B506D250B291200FAECFB /* BlurHashDecode.swift in Sources */,
|
D67B506D250B291200FAECFB /* BlurHashDecode.swift in Sources */,
|
||||||
D62275A024F1677200B82A16 /* ComposeHostingController.swift in Sources */,
|
D62275A024F1677200B82A16 /* ComposeHostingController.swift in Sources */,
|
||||||
|
|
|
@ -15,9 +15,6 @@ protocol ComposeHostingControllerDelegate: AnyObject {
|
||||||
func dismissCompose(mode: ComposeUIState.DismissMode) -> Bool
|
func dismissCompose(mode: ComposeUIState.DismissMode) -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
private let VISIBILITY_BAR_BUTTON_TAG = 42001
|
|
||||||
private let LOCAL_ONLY_BAR_BUTTON_TAG = 42002
|
|
||||||
|
|
||||||
class ComposeHostingController: UIHostingController<ComposeContainerView> {
|
class ComposeHostingController: UIHostingController<ComposeContainerView> {
|
||||||
|
|
||||||
weak var delegate: ComposeHostingControllerDelegate?
|
weak var delegate: ComposeHostingControllerDelegate?
|
||||||
|
@ -135,12 +132,12 @@ class ComposeHostingController: UIHostingController<ComposeContainerView> {
|
||||||
items.append(UIBarButtonItem(title: "CW", style: .plain, target: self, action: #selector(cwButtonPressed)))
|
items.append(UIBarButtonItem(title: "CW", style: .plain, target: self, action: #selector(cwButtonPressed)))
|
||||||
|
|
||||||
let visibilityItem = UIBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
|
let visibilityItem = UIBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
|
||||||
visibilityItem.tag = VISIBILITY_BAR_BUTTON_TAG
|
visibilityItem.tag = ViewTags.composeVisibilityBarButton
|
||||||
items.append(visibilityItem)
|
items.append(visibilityItem)
|
||||||
|
|
||||||
if mastodonController.instanceFeatures.localOnlyPosts {
|
if mastodonController.instanceFeatures.localOnlyPosts {
|
||||||
let item = UIBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
|
let item = UIBarButtonItem(image: nil, style: .plain, target: nil, action: nil)
|
||||||
item.tag = LOCAL_ONLY_BAR_BUTTON_TAG
|
item.tag = ViewTags.composeLocalOnlyBarButton
|
||||||
items.append(item)
|
items.append(item)
|
||||||
localOnlyChanged(draft.localOnly)
|
localOnlyChanged(draft.localOnly)
|
||||||
}
|
}
|
||||||
|
@ -243,7 +240,7 @@ class ComposeHostingController: UIHostingController<ComposeContainerView> {
|
||||||
|
|
||||||
private func visibilityChanged(_ newVisibility: Status.Visibility) {
|
private func visibilityChanged(_ newVisibility: Status.Visibility) {
|
||||||
for toolbar in [mainToolbar, inputAccessoryToolbar] {
|
for toolbar in [mainToolbar, inputAccessoryToolbar] {
|
||||||
guard let item = toolbar?.items?.first(where: { $0.tag == VISIBILITY_BAR_BUTTON_TAG }) else {
|
guard let item = toolbar?.items?.first(where: { $0.tag == ViewTags.composeVisibilityBarButton }) else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
item.image = UIImage(systemName: newVisibility.imageName)
|
item.image = UIImage(systemName: newVisibility.imageName)
|
||||||
|
@ -260,7 +257,7 @@ class ComposeHostingController: UIHostingController<ComposeContainerView> {
|
||||||
|
|
||||||
private func localOnlyChanged(_ localOnly: Bool) {
|
private func localOnlyChanged(_ localOnly: Bool) {
|
||||||
for toolbar in [mainToolbar, inputAccessoryToolbar] {
|
for toolbar in [mainToolbar, inputAccessoryToolbar] {
|
||||||
guard let item = toolbar?.items?.first(where: { $0.tag == LOCAL_ONLY_BAR_BUTTON_TAG }) else {
|
guard let item = toolbar?.items?.first(where: { $0.tag == ViewTags.composeLocalOnlyBarButton }) else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if localOnly {
|
if localOnly {
|
||||||
|
|
|
@ -46,7 +46,9 @@ class MainSplitViewController: UISplitViewController {
|
||||||
setViewController(sidebar, for: .primary)
|
setViewController(sidebar, for: .primary)
|
||||||
primaryBackgroundStyle = .sidebar
|
primaryBackgroundStyle = .sidebar
|
||||||
|
|
||||||
setViewController(EnhancedNavigationViewController(), for: .secondary)
|
let secondaryNav = EnhancedNavigationViewController()
|
||||||
|
secondaryNav.useBrowserStyleNavigation = true
|
||||||
|
setViewController(secondaryNav, for: .secondary)
|
||||||
// don't unnecesarily construct a content VC unless the we're in actually split mode
|
// don't unnecesarily construct a content VC unless the we're in actually split mode
|
||||||
// when we change from compact -> split for the first time, the VC will be transferred anyways
|
// when we change from compact -> split for the first time, the VC will be transferred anyways
|
||||||
if traitCollection.horizontalSizeClass != .compact {
|
if traitCollection.horizontalSizeClass != .compact {
|
||||||
|
|
|
@ -141,7 +141,9 @@ class MainTabBarViewController: UITabBarController, UITabBarControllerDelegate {
|
||||||
if let vc = vc as? UINavigationController {
|
if let vc = vc as? UINavigationController {
|
||||||
return vc
|
return vc
|
||||||
} else {
|
} else {
|
||||||
return EnhancedNavigationViewController(rootViewController: vc)
|
let nav = EnhancedNavigationViewController(rootViewController: vc)
|
||||||
|
nav.useBrowserStyleNavigation = true
|
||||||
|
return nav
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,42 +10,68 @@ import UIKit
|
||||||
|
|
||||||
class EnhancedNavigationViewController: UINavigationController {
|
class EnhancedNavigationViewController: UINavigationController {
|
||||||
|
|
||||||
|
var useBrowserStyleNavigation = false
|
||||||
|
|
||||||
var poppedViewControllers = [UIViewController]()
|
var poppedViewControllers = [UIViewController]()
|
||||||
var skipResetPoppedOnNextPush = false
|
var skipResetPoppedOnNextPush = false
|
||||||
|
|
||||||
private var interactivePushTransition: InteractivePushTransition!
|
private var interactivePushTransition: InteractivePushTransition!
|
||||||
|
|
||||||
|
override var viewControllers: [UIViewController] {
|
||||||
|
didSet {
|
||||||
|
poppedViewControllers = []
|
||||||
|
for vc in viewControllers {
|
||||||
|
configureNavItem(vc.navigationItem)
|
||||||
|
}
|
||||||
|
updateTopNavItemState()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
self.interactivePushTransition = InteractivePushTransition(navigationController: self)
|
self.interactivePushTransition = InteractivePushTransition(navigationController: self)
|
||||||
|
|
||||||
|
if let topViewController {
|
||||||
|
configureNavItem(topViewController.navigationItem)
|
||||||
|
updateTopNavItemState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func popViewController(animated: Bool) -> UIViewController? {
|
override func popViewController(animated: Bool) -> UIViewController? {
|
||||||
if let popped = super.popViewController(animated: animated) {
|
let popped = performAfterAnimating(block: {
|
||||||
|
super.popViewController(animated: animated)
|
||||||
|
}, after: {
|
||||||
|
self.updateTopNavItemState()
|
||||||
|
}, animated: animated)
|
||||||
|
if let popped {
|
||||||
poppedViewControllers.insert(popped, at: 0)
|
poppedViewControllers.insert(popped, at: 0)
|
||||||
return popped
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
return popped
|
||||||
}
|
}
|
||||||
|
|
||||||
override func popToRootViewController(animated: Bool) -> [UIViewController]? {
|
override func popToRootViewController(animated: Bool) -> [UIViewController]? {
|
||||||
if let popped = super.popToRootViewController(animated: animated) {
|
let popped = performAfterAnimating(block: {
|
||||||
|
super.popToRootViewController(animated: animated)
|
||||||
|
}, after: {
|
||||||
|
self.updateTopNavItemState()
|
||||||
|
}, animated: animated)
|
||||||
|
if let popped {
|
||||||
poppedViewControllers = popped
|
poppedViewControllers = popped
|
||||||
return popped
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
return popped
|
||||||
}
|
}
|
||||||
|
|
||||||
override func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? {
|
override func popToViewController(_ viewController: UIViewController, animated: Bool) -> [UIViewController]? {
|
||||||
if let popped = super.popToViewController(viewController, animated: animated) {
|
let popped = performAfterAnimating(block: {
|
||||||
|
super.popToViewController(viewController, animated: animated)
|
||||||
|
}, after: {
|
||||||
|
self.updateTopNavItemState()
|
||||||
|
}, animated: animated)
|
||||||
|
if let popped {
|
||||||
poppedViewControllers.insert(contentsOf: popped, at: 0)
|
poppedViewControllers.insert(contentsOf: popped, at: 0)
|
||||||
return popped
|
|
||||||
} else {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
return popped
|
||||||
}
|
}
|
||||||
|
|
||||||
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
|
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
|
||||||
|
@ -54,7 +80,43 @@ class EnhancedNavigationViewController: UINavigationController {
|
||||||
} else {
|
} else {
|
||||||
self.poppedViewControllers = []
|
self.poppedViewControllers = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configureNavItem(viewController.navigationItem)
|
||||||
|
|
||||||
super.pushViewController(viewController, animated: animated)
|
super.pushViewController(viewController, animated: animated)
|
||||||
|
|
||||||
|
updateTopNavItemState()
|
||||||
|
}
|
||||||
|
|
||||||
|
func pushPoppedViewController() {
|
||||||
|
guard !poppedViewControllers.isEmpty else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
skipResetPoppedOnNextPush = true
|
||||||
|
pushViewController(poppedViewControllers.removeFirst(), animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pushToPoppedViewController(_ target: UIViewController) {
|
||||||
|
guard poppedViewControllers.contains(target) else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var toInsert: [UIViewController] = []
|
||||||
|
while true {
|
||||||
|
let vc = poppedViewControllers.removeFirst()
|
||||||
|
if vc == target {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
toInsert.append(vc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// match the system behavior when popping multiple by animated-ly pushing the final destination one,
|
||||||
|
// and then intersiting the intermediary ones before it, as if they'd all been pushed together
|
||||||
|
performAfterAnimating(block: {
|
||||||
|
pushViewController(target, animated: true)
|
||||||
|
}, after: {
|
||||||
|
self.viewControllers.insert(contentsOf: toInsert, at: self.viewControllers.count - 1)
|
||||||
|
self.updateTopNavItemState()
|
||||||
|
}, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func onWillShow() {
|
func onWillShow() {
|
||||||
|
@ -73,6 +135,92 @@ class EnhancedNavigationViewController: UINavigationController {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func configureNavItem(_ navItem: UINavigationItem) {
|
||||||
|
guard useBrowserStyleNavigation,
|
||||||
|
UIDevice.current.userInterfaceIdiom != .phone else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
navItem.style = .browser
|
||||||
|
navItem.hidesBackButton = true
|
||||||
|
if let titleView = navItem.titleView,
|
||||||
|
titleView.tag != ViewTags.navEmptyTitleView {
|
||||||
|
// blergh, i don't like changing this out from under some other view controller
|
||||||
|
// we use an empty view because otherwise the title label displays in addition to the new title view bar button item
|
||||||
|
navItem.titleView = UIView()
|
||||||
|
navItem.titleView?.tag = ViewTags.navEmptyTitleView
|
||||||
|
// TODO: centerItemGroups don't animate out during nav transitions, the just (dis)appear abruptly
|
||||||
|
navItem.centerItemGroups = [
|
||||||
|
.fixedGroup(items: [UIBarButtonItem(customView: titleView)])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
let back = UIBarButtonItem(image: UIImage(systemName: "chevron.backward"), style: .plain, target: self, action: #selector(goBack))
|
||||||
|
back.tag = ViewTags.navBackBarButton
|
||||||
|
back.menu = UIMenu(children: [
|
||||||
|
UIDeferredMenuElement({ [unowned self] completion in
|
||||||
|
completion(self.viewControllers.dropLast(1).reversed().map { vc in
|
||||||
|
UIAction(title: vc.navigationItem.title ?? "Back") { [weak self] _ in
|
||||||
|
_ = self?.popToViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
])
|
||||||
|
let forward = UIBarButtonItem(image: UIImage(systemName: "chevron.forward"), style: .plain, target: self, action: #selector(goForward))
|
||||||
|
forward.tag = ViewTags.navForwardBarButton
|
||||||
|
forward.menu = UIMenu(children: [
|
||||||
|
UIDeferredMenuElement.uncached({ [unowned self] completion in
|
||||||
|
completion(poppedViewControllers.map { vc in
|
||||||
|
UIAction(title: vc.navigationItem.title ?? "Forward") { [weak self] _ in
|
||||||
|
self?.pushToPoppedViewController(vc)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
])
|
||||||
|
navItem.leadingItemGroups = [
|
||||||
|
.fixedGroup(items: [
|
||||||
|
back,
|
||||||
|
forward,
|
||||||
|
])
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateTopNavItemState() {
|
||||||
|
guard useBrowserStyleNavigation,
|
||||||
|
UIDevice.current.userInterfaceIdiom != .phone,
|
||||||
|
let vc = topViewController,
|
||||||
|
let group = vc.navigationItem.leadingItemGroups.first,
|
||||||
|
group.barButtonItems.count == 2,
|
||||||
|
group.barButtonItems[0].tag == ViewTags.navBackBarButton,
|
||||||
|
group.barButtonItems[1].tag == ViewTags.navForwardBarButton else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
group.barButtonItems[0].isEnabled = viewControllers.count > 1
|
||||||
|
group.barButtonItems[1].isEnabled = !poppedViewControllers.isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
|
private func performAfterAnimating<R>(block: () -> R, after: @escaping () -> Void, animated: Bool) -> R {
|
||||||
|
if animated {
|
||||||
|
CATransaction.begin()
|
||||||
|
let result = block()
|
||||||
|
CATransaction.setCompletionBlock {
|
||||||
|
after()
|
||||||
|
}
|
||||||
|
CATransaction.commit()
|
||||||
|
return result
|
||||||
|
} else {
|
||||||
|
let result = block()
|
||||||
|
after()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func goBack() {
|
||||||
|
_ = popViewController(animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func goForward() {
|
||||||
|
pushPoppedViewController()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension EnhancedNavigationViewController: BackgroundableViewController {
|
extension EnhancedNavigationViewController: BackgroundableViewController {
|
||||||
|
|
|
@ -24,6 +24,12 @@ class SegmentedPageViewController: UIPageViewController, UIPageViewControllerDel
|
||||||
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
|
super.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)
|
||||||
|
|
||||||
self.delegate = self
|
self.delegate = self
|
||||||
|
|
||||||
|
// this needs to happen in init because EnhancedNavigationViewController expects to be able to look at the titleView
|
||||||
|
// before the view has necessarily loaded
|
||||||
|
segmentedControl = UISegmentedControl(items: titles)
|
||||||
|
segmentedControl.addTarget(self, action: #selector(segmentedControlChanged), for: .valueChanged)
|
||||||
|
navigationItem.titleView = segmentedControl
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
|
@ -35,10 +41,6 @@ class SegmentedPageViewController: UIPageViewController, UIPageViewControllerDel
|
||||||
|
|
||||||
view.backgroundColor = .systemBackground
|
view.backgroundColor = .systemBackground
|
||||||
|
|
||||||
segmentedControl = UISegmentedControl(items: titles)
|
|
||||||
segmentedControl.addTarget(self, action: #selector(segmentedControlChanged), for: .valueChanged)
|
|
||||||
navigationItem.titleView = segmentedControl
|
|
||||||
|
|
||||||
segmentedControl.selectedSegmentIndex = 0
|
segmentedControl.selectedSegmentIndex = 0
|
||||||
selectPage(at: 0, animated: false)
|
selectPage(at: 0, animated: false)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
//
|
||||||
|
// ViewTags.swift
|
||||||
|
// Tusker
|
||||||
|
//
|
||||||
|
// Created by Shadowfacts on 6/8/22.
|
||||||
|
// Copyright © 2022 Shadowfacts. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct ViewTags {
|
||||||
|
private init() {}
|
||||||
|
|
||||||
|
static let composeVisibilityBarButton = 42001
|
||||||
|
static let composeLocalOnlyBarButton = 42002
|
||||||
|
static let navBackBarButton = 42003
|
||||||
|
static let navForwardBarButton = 42004
|
||||||
|
static let navEmptyTitleView = 42005
|
||||||
|
}
|
Loading…
Reference in New Issue