Skip to content

Commit

Permalink
Merge branch 'fix-swiftlint-warnings-in-xcode-ios-RootContainerViewCo…
Browse files Browse the repository at this point in the history
…ntroller-296'
  • Loading branch information
buggmagnet committed Sep 12, 2023
2 parents e05cc2a + 4ecd728 commit b952fff
Showing 1 changed file with 130 additions and 69 deletions.
199 changes: 130 additions & 69 deletions ios/MullvadVPN/Containers/Root/RootContainerViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -484,54 +484,141 @@ class RootContainerViewController: UIViewController {
// hide in-App notificationBanner when the container decides to keep it invisible
isNavigationBarHidden = (targetViewController as? RootContainment)?.prefersNotificationBarHidden ?? false

let finishTransition = {
/*
Finish transition appearance.
Note this has to be done before the call to `didMove(to:)` or `removeFromParent()`
otherwise `endAppearanceTransition()` will fire `didMove(to:)` twice.
*/
if shouldHandleAppearanceEvents {
if let targetViewController,
sourceViewController != targetViewController {
self.endChildControllerTransition(targetViewController)
}

if let sourceViewController,
sourceViewController != targetViewController {
self.endChildControllerTransition(sourceViewController)
}
}
configureViewControllers(
viewControllersToAdd: viewControllersToAdd,
newViewControllers: newViewControllers,
targetViewController: targetViewController,
viewControllersToRemove: viewControllersToRemove
)

beginTransition(
shouldHandleAppearanceEvents: shouldHandleAppearanceEvents,
targetViewController: targetViewController,
shouldAnimate: shouldAnimate,
sourceViewController: sourceViewController
)

let finishTransition = { [weak self] in
self?.onTransitionEnd(
shouldHandleAppearanceEvents: shouldHandleAppearanceEvents,
sourceViewController: sourceViewController,
targetViewController: targetViewController,
viewControllersToAdd: viewControllersToAdd,
viewControllersToRemove: viewControllersToRemove
)

completion?()
}

// Notify the added controllers that they finished a transition into the container
for child in viewControllersToAdd {
child.didMove(toParent: self)
let alongSideAnimations = { [weak self] in
guard let self else { return }

updateHeaderBarStyleFromChildPreferences(animated: shouldAnimate)
updateHeaderBarHiddenFromChildPreferences(animated: shouldAnimate)
updateNotificationBarHiddenFromChildPreferences()
updateDeviceInfoBarHiddenFromChildPreferences()
}

if shouldAnimate {
CATransaction.begin()
CATransaction.setCompletionBlock {
finishTransition()
}

// Remove the controllers that transitioned out of the container
// The call to removeFromParent() automatically calls child.didMove()
for child in viewControllersToRemove {
child.view.removeFromSuperview()
child.removeFromParent()
animateTransition(
sourceViewController: sourceViewController,
newViewControllers: newViewControllers,
targetViewController: targetViewController,
isUnwinding: isUnwinding,
alongSideAnimations: alongSideAnimations
)

CATransaction.commit()
} else {
alongSideAnimations()
finishTransition()
}
}

private func animateTransition(
sourceViewController: UIViewController?,
newViewControllers: [UIViewController],
targetViewController: UIViewController?,
isUnwinding: Bool,
alongSideAnimations: () -> Void
) {
let transition = CATransition()
transition.duration = 0.35
transition.type = .push

// Pick the animation movement direction
let sourceIndex = sourceViewController.flatMap { newViewControllers.firstIndex(of: $0) }
let targetIndex = targetViewController.flatMap { newViewControllers.firstIndex(of: $0) }

switch (sourceIndex, targetIndex) {
case let (.some(lhs), .some(rhs)):
transition.subtype = lhs > rhs ? .fromLeft : .fromRight
case (.none, .some):
transition.subtype = isUnwinding ? .fromLeft : .fromRight
default:
transition.subtype = .fromRight
}

transitionContainer.layer.add(transition, forKey: "transition")
alongSideAnimations()
}

private func onTransitionEnd(
shouldHandleAppearanceEvents: Bool,
sourceViewController: UIViewController?,
targetViewController: UIViewController?,
viewControllersToAdd: [UIViewController],
viewControllersToRemove: [UIViewController]
) {
/*
Finish transition appearance.
Note this has to be done before the call to `didMove(to:)` or `removeFromParent()`
otherwise `endAppearanceTransition()` will fire `didMove(to:)` twice.
*/
if shouldHandleAppearanceEvents {
if let targetViewController,
sourceViewController != targetViewController {
self.endChildControllerTransition(targetViewController)
}

// Remove the source controller from view hierarchy
if sourceViewController != targetViewController {
sourceViewController?.view.removeFromSuperview()
if let sourceViewController,
sourceViewController != targetViewController {
self.endChildControllerTransition(sourceViewController)
}
}

self.updateInterfaceOrientation(attemptRotateToDeviceOrientation: true)
self.updateAccessibilityElementsAndNotifyScreenChange()
// Notify the added controllers that they finished a transition into the container
for child in viewControllersToAdd {
child.didMove(toParent: self)
}

completion?()
// Remove the controllers that transitioned out of the container
// The call to removeFromParent() automatically calls child.didMove()
for child in viewControllersToRemove {
child.view.removeFromSuperview()
child.removeFromParent()
}

let alongSideAnimations = {
self.updateHeaderBarStyleFromChildPreferences(animated: shouldAnimate)
self.updateHeaderBarHiddenFromChildPreferences(animated: shouldAnimate)
self.updateNotificationBarHiddenFromChildPreferences()
self.updateDeviceInfoBarHiddenFromChildPreferences()
// Remove the source controller from view hierarchy
if sourceViewController != targetViewController {
sourceViewController?.view.removeFromSuperview()
}

self.updateInterfaceOrientation(attemptRotateToDeviceOrientation: true)
self.updateAccessibilityElementsAndNotifyScreenChange()
}

private func configureViewControllers(
viewControllersToAdd: [UIViewController],
newViewControllers: [UIViewController],
targetViewController: UIViewController?,
viewControllersToRemove: [UIViewController]
) {
// Add new child controllers. The call to addChild() automatically calls child.willMove()
// Children have to be registered in the container for Storyboard unwind segues to function
// properly, however the child controller views don't have to be added immediately, and
Expand All @@ -558,8 +645,14 @@ class RootContainerViewController: UIViewController {
}

viewControllers = newViewControllers
}

// Begin appearance transition
private func beginTransition(
shouldHandleAppearanceEvents: Bool,
targetViewController: UIViewController?,
shouldAnimate: Bool,
sourceViewController: UIViewController?
) {
if shouldHandleAppearanceEvents {
if let sourceViewController,
sourceViewController != targetViewController {
Expand All @@ -579,38 +672,6 @@ class RootContainerViewController: UIViewController {
}
setNeedsStatusBarAppearanceUpdate()
}

if shouldAnimate {
CATransaction.begin()
CATransaction.setCompletionBlock {
finishTransition()
}

let transition = CATransition()
transition.duration = 0.35
transition.type = .push

// Pick the animation movement direction
let sourceIndex = sourceViewController.flatMap { newViewControllers.firstIndex(of: $0) }
let targetIndex = targetViewController.flatMap { newViewControllers.firstIndex(of: $0) }

switch (sourceIndex, targetIndex) {
case let (.some(lhs), .some(rhs)):
transition.subtype = lhs > rhs ? .fromLeft : .fromRight
case (.none, .some):
transition.subtype = isUnwinding ? .fromLeft : .fromRight
default:
transition.subtype = .fromRight
}

transitionContainer.layer.add(transition, forKey: "transition")
alongSideAnimations()

CATransaction.commit()
} else {
alongSideAnimations()
finishTransition()
}
}

private func addChildView(_ childView: UIView) {
Expand Down

0 comments on commit b952fff

Please sign in to comment.