/// <summary> /// Hides a modal frame. /// </summary> /// <param name="previousFrameName">The name of the modal frame to close.</param> /// <param name="nextFrameName">The name of the frame that will be revealed as a result of closing the modal.</param> /// <param name="transitionInfo">The transition info describing the animation.</param> public async Task CloseModal(string previousFrameName, string nextFrameName, FrameSectionsTransitionInfo transitionInfo) // Runs on background thread. { await HidePreviousFrameAndShowNextFrame(previousFrameName, nextFrameName, UpdateView); async Task UpdateView(FrameInfo previousFrame, FrameInfo nextFrame) // Runs on the UI thread { switch (transitionInfo) { case DelegatingFrameSectionsTransitionInfo frameTransition: await frameTransition.Run(frameToHide : previousFrame.Frame, frameToShow : nextFrame.Frame, frameToShowIsAboveFrameToHide : false); break; case UIViewControllerSectionsTransitionInfo viewControllerTransitionInfo: await previousFrame.ModalViewController.Close(viewControllerTransitionInfo); break; default: throw new InvalidOperationException($"Unsupported transition info type '{transitionInfo.GetType()}'."); } } }
/// <summary> /// Changes the active section. /// </summary> /// <param name="previousFrameName">The name of the frame that will no longer be active.</param> /// <param name="nextFrameName">The name of the frame that will be active.</param> /// <param name="transitionInfo">The transition info describing the animation.</param> public async Task ChangeActiveSection(string previousFrameName, string nextFrameName, FrameSectionsTransitionInfo transitionInfo) // Runs on background thread. { await HidePreviousFrameAndShowNextFrame(previousFrameName, nextFrameName, UpdateView); async Task UpdateView(FrameInfo previousFrame, FrameInfo nextFrame) // Runs on the UI thread { switch (transitionInfo) { case DelegatingFrameSectionsTransitionInfo frameTransition: if (previousFrame.Index > nextFrame.Index) { // If the previous frame is on top of the next one, we hide the previous frame to reveal the next one underneath. // 1. We must first hide all frames that would be visible between our two target frames. var framesToHideInstantly = _frames.Values .Where(f => f.State == FrameState.Shown && f.Index > nextFrame.Index && f.Index < previousFrame.Index); foreach (var f in framesToHideInstantly) { f.Frame.Visibility = Visibility.Collapsed; f.State = FrameState.Hidden; } // 2. Animate the previous frame await frameTransition.Run(frameToHide : previousFrame.Frame, frameToShow : nextFrame.Frame, frameToShowIsAboveFrameToHide : false); // 3. Once faded out, collapse the previous frame. previousFrame.Frame.Visibility = Visibility.Collapsed; } else { // Otherwise, the next frame is displayed on top of the previous one. await frameTransition.Run(frameToHide : previousFrame.Frame, frameToShow : nextFrame.Frame, frameToShowIsAboveFrameToHide : true); // 5. Collapse the previous frame that is no longer visible. previousFrame.Frame.Visibility = Visibility.Collapsed; } break; case UIViewControllerSectionsTransitionInfo viewControllerTransitionInfo: throw new InvalidOperationException($"UIViewControllerTransitionInfo is only supported for modal operations."); default: throw new InvalidOperationException($"Unsupported transition info type '{transitionInfo.GetType()}'."); } } }