2 * Copyright(c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 using System.Collections.Generic;
20 using System.ComponentModel;
21 using Tizen.NUI.BaseComponents;
22 using Tizen.NUI.Binding;
24 namespace Tizen.NUI.Components
27 /// PoppedEventArgs is a class to record <see cref="Navigator.Popped"/> event arguments which will be sent to user.
29 /// <since_tizen> 9 </since_tizen>
30 public class PoppedEventArgs : EventArgs
33 /// Page popped by Navigator.
35 /// <since_tizen> 9 </since_tizen>
36 public Page Page { get; internal set; }
40 /// The Navigator is a class which navigates pages with stack methods such as Push and Pop.
43 /// With Transition class, Navigator supports smooth transition of View pair between two Pages
44 /// by using <see cref="PushWithTransition(Page)"/> and <see cref="PopWithTransition()"/> methods.
45 /// If current top Page and next top Page have <see cref="View"/>s those have same TransitionTag,
46 /// Navigator creates smooth transition motion for them.
47 /// Navigator.Transition property can be used to set properties of the Transition such as TimePeriod and AlphaFunction.
48 /// When all transitions are finished, Navigator calls a callback methods those connected on the "TransitionFinished" event.
52 /// Navigator navigator = new Navigator()
54 /// TimePeriod = new TimePeriod(500),
55 /// AlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseInOutSine)
58 /// View view = new View()
60 /// TransitionOptions = new TransitionOptions()
62 /// /* Set properties for the transition of this View */
66 /// ContentPage newPage = new ContentPage()
71 /// Navigator.PushWithTransition(newPage);
74 /// <since_tizen> 9 </since_tizen>
75 public class Navigator : Control
78 /// TransitionProperty
80 [EditorBrowsable(EditorBrowsableState.Never)]
81 public static readonly BindableProperty TransitionProperty = BindableProperty.Create(nameof(Transition), typeof(Transition), typeof(Navigator), null, propertyChanged: (bindable, oldValue, newValue) =>
83 var instance = (Navigator)bindable;
86 instance.InternalTransition = newValue as Transition;
89 defaultValueCreator: (bindable) =>
91 var instance = (Navigator)bindable;
92 return instance.InternalTransition;
95 private const int DefaultTransitionDuration = 300;
97 //This will be replaced with view transition class instance.
98 private Animation curAnimation = null;
100 //This will be replaced with view transition class instance.
101 private Animation newAnimation = null;
103 private TransitionSet transitionSet = null;
105 private Transition transition = new Transition()
107 TimePeriod = new TimePeriod(DefaultTransitionDuration),
108 AlphaFunction = new AlphaFunction(AlphaFunction.BuiltinFunctions.Default),
111 private bool transitionFinished = true;
113 //TODO: Needs to consider how to remove disposed window from dictionary.
114 //Two dictionaries are required to remove disposed navigator from dictionary.
115 private static Dictionary<Window, Navigator> windowNavigator = new Dictionary<Window, Navigator>();
116 private static Dictionary<Navigator, Window> navigatorWindow = new Dictionary<Navigator, Window>();
118 private List<Page> navigationPages = new List<Page>();
120 private void Initialize()
122 Layout = new AbsoluteLayout();
126 /// Creates a new instance of a Navigator.
128 /// <since_tizen> 9 </since_tizen>
129 public Navigator() : base()
135 /// Creates a new instance of Navigator with style.
137 /// <param name="style">Creates Navigator by special style defined in UX.</param>
138 [EditorBrowsable(EditorBrowsableState.Never)]
139 public Navigator(string style) : base(style)
145 /// Creates a new instance of a Navigator with style.
147 /// <param name="style">A style applied to the newly created Navigator.</param>
148 [EditorBrowsable(EditorBrowsableState.Never)]
149 public Navigator(ControlStyle style) : base(style)
155 [EditorBrowsable(EditorBrowsableState.Never)]
156 public override void OnInitialize()
160 AccessibilityRole = Role.PageTabList;
164 /// An event fired when Transition has been finished.
166 /// <since_tizen> 9 </since_tizen>
167 public event EventHandler<EventArgs> TransitionFinished;
170 /// An event fired when Pop of a page has been finished.
173 /// When you free resources in the Popped event handler, please make sure if the popped page is the page you find.
175 /// <since_tizen> 9 </since_tizen>
176 public event EventHandler<PoppedEventArgs> Popped;
179 /// Returns the count of pages in Navigator.
181 /// <since_tizen> 9 </since_tizen>
182 public int PageCount => navigationPages.Count;
185 /// Transition properties for the transition of View pair having same transition tag.
187 /// <since_tizen> 9 </since_tizen>
188 public Transition Transition
192 return GetValue(TransitionProperty) as Transition;
196 SetValue(TransitionProperty, value);
197 NotifyPropertyChanged();
200 private Transition InternalTransition
213 /// Pushes a page to Navigator.
214 /// If the page is already in Navigator, then it is not pushed.
216 /// <param name="page">The page to push to Navigator.</param>
217 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
218 /// <since_tizen> 9 </since_tizen>
219 public void PushWithTransition(Page page)
221 if (!transitionFinished)
223 Tizen.Log.Error("NUI", "Transition is still not finished.\n");
229 throw new ArgumentNullException(nameof(page), "page should not be null.");
232 //Duplicate page is not pushed.
233 if (navigationPages.Contains(page)) return;
235 var topPage = Peek();
243 navigationPages.Add(page);
245 page.Navigator = this;
248 page.InvokeAppearing();
249 topPage.InvokeDisappearing();
250 topPage.SaveKeyFocus();
252 transitionSet = CreateTransitions(topPage, page, true);
253 transitionSet.Finished += (object sender, EventArgs e) =>
255 if (page is DialogPage == false)
257 topPage.SetVisible(false);
260 // Need to update Content of the new page
261 ShowContentOfPage(page);
264 page.InvokeAppeared();
265 page.RestoreKeyFocus();
267 topPage.InvokeDisappeared();
268 NotifyAccessibilityStatesChangeOfPages(topPage, page);
270 transitionFinished = false;
274 /// Pops the top page from Navigator.
276 /// <returns>The popped page.</returns>
277 /// <exception cref="InvalidOperationException">Thrown when there is no page in Navigator.</exception>
278 /// <since_tizen> 9 </since_tizen>
279 public Page PopWithTransition()
281 if (!transitionFinished)
283 Tizen.Log.Error("NUI", "Transition is still not finished.\n");
287 if (navigationPages.Count == 0)
289 throw new InvalidOperationException("There is no page in Navigator.");
292 var topPage = Peek();
294 if (navigationPages.Count == 1)
298 //Invoke Popped event
299 Popped?.Invoke(this, new PoppedEventArgs() { Page = topPage });
303 var newTopPage = navigationPages[navigationPages.Count - 2];
306 newTopPage.InvokeAppearing();
307 topPage.InvokeDisappearing();
308 topPage.SaveKeyFocus();
310 transitionSet = CreateTransitions(topPage, newTopPage, false);
311 transitionSet.Finished += (object sender, EventArgs e) =>
314 topPage.SetVisible(true);
316 // Need to update Content of the new page
317 ShowContentOfPage(newTopPage);
320 newTopPage.InvokeAppeared();
321 newTopPage.RestoreKeyFocus();
323 topPage.InvokeDisappeared();
325 //Invoke Popped event
326 Popped?.Invoke(this, new PoppedEventArgs() { Page = topPage });
328 transitionFinished = false;
334 /// Pushes a page to Navigator.
335 /// If the page is already in Navigator, then it is not pushed.
337 /// <param name="page">The page to push to Navigator.</param>
338 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
339 /// <since_tizen> 9 </since_tizen>
340 public void Push(Page page)
342 if (!transitionFinished)
344 Tizen.Log.Error("NUI", "Transition is still not finished.\n");
350 throw new ArgumentNullException(nameof(page), "page should not be null.");
353 //Duplicate page is not pushed.
354 if (navigationPages.Contains(page)) return;
364 navigationPages.Add(page);
366 page.Navigator = this;
369 page.InvokeAppearing();
370 curTop.InvokeDisappearing();
372 curTop.SaveKeyFocus();
374 //TODO: The following transition codes will be replaced with view transition.
375 InitializeAnimation();
377 if (page is DialogPage == false)
379 curAnimation = new Animation(DefaultTransitionDuration);
380 curAnimation.AnimateTo(curTop, "PositionX", 0.0f, 0, DefaultTransitionDuration);
381 curAnimation.EndAction = Animation.EndActions.StopFinal;
382 curAnimation.Finished += (object sender, EventArgs args) =>
384 curTop.SetVisible(false);
387 curTop.InvokeDisappeared();
391 page.PositionX = SizeWidth;
392 page.SetVisible(true);
393 // Set Content visible because it was hidden by HideContentOfPage.
394 (page as ContentPage)?.Content?.SetVisible(true);
396 newAnimation = new Animation(DefaultTransitionDuration);
397 newAnimation.AnimateTo(page, "PositionX", 0.0f, 0, DefaultTransitionDuration);
398 newAnimation.EndAction = Animation.EndActions.StopFinal;
399 newAnimation.Finished += (object sender, EventArgs e) =>
401 // Need to update Content of the new page
402 ShowContentOfPage(page);
405 page.InvokeAppeared();
406 NotifyAccessibilityStatesChangeOfPages(curTop, page);
408 page.RestoreKeyFocus();
414 ShowContentOfPage(page);
415 page.RestoreKeyFocus();
420 /// Pops the top page from Navigator.
422 /// <returns>The popped page.</returns>
423 /// <exception cref="InvalidOperationException">Thrown when there is no page in Navigator.</exception>
424 /// <since_tizen> 9 </since_tizen>
427 if (!transitionFinished)
429 Tizen.Log.Error("NUI", "Transition is still not finished.\n");
433 if (navigationPages.Count == 0)
435 throw new InvalidOperationException("There is no page in Navigator.");
440 if (navigationPages.Count == 1)
444 //Invoke Popped event
445 Popped?.Invoke(this, new PoppedEventArgs() { Page = curTop });
450 var newTop = navigationPages[navigationPages.Count - 2];
453 newTop.InvokeAppearing();
454 curTop.InvokeDisappearing();
455 curTop.SaveKeyFocus();
457 //TODO: The following transition codes will be replaced with view transition.
458 InitializeAnimation();
460 if (curTop is DialogPage == false)
462 curAnimation = new Animation(DefaultTransitionDuration);
463 curAnimation.AnimateTo(curTop, "PositionX", SizeWidth, 0, DefaultTransitionDuration);
464 curAnimation.EndAction = Animation.EndActions.StopFinal;
465 curAnimation.Finished += (object sender, EventArgs e) =>
467 //Removes the current top page after transition is finished.
469 curTop.PositionX = 0.0f;
472 curTop.InvokeDisappeared();
474 //Invoke Popped event
475 Popped?.Invoke(this, new PoppedEventArgs() { Page = curTop });
479 newTop.SetVisible(true);
480 // Set Content visible because it was hidden by HideContentOfPage.
481 (newTop as ContentPage)?.Content?.SetVisible(true);
483 newAnimation = new Animation(DefaultTransitionDuration);
484 newAnimation.AnimateTo(newTop, "PositionX", 0.0f, 0, DefaultTransitionDuration);
485 newAnimation.EndAction = Animation.EndActions.StopFinal;
486 newAnimation.Finished += (object sender, EventArgs e) =>
488 // Need to update Content of the new page
489 ShowContentOfPage(newTop);
492 newTop.InvokeAppeared();
494 newTop.RestoreKeyFocus();
501 newTop.RestoreKeyFocus();
508 /// Returns the page of the given index in Navigator.
509 /// The indices of pages in Navigator are basically the order of pushing or inserting to Navigator.
510 /// So a page's index in Navigator can be changed whenever push/insert or pop/remove occurs.
512 /// <param name="index">The index of a page in Navigator.</param>
513 /// <returns>The page of the given index in Navigator.</returns>
514 /// <exception cref="ArgumentOutOfRangeException">Thrown when the argument index is less than 0, or greater than the number of pages.</exception>
515 public Page GetPage(int index)
517 if ((index < 0) || (index > navigationPages.Count))
519 throw new ArgumentOutOfRangeException(nameof(index), "index should be greater than or equal to 0, and less than or equal to the number of pages.");
522 return navigationPages[index];
526 /// Returns the current index of the given page in Navigator.
527 /// The indices of pages in Navigator are basically the order of pushing or inserting to Navigator.
528 /// So a page's index in Navigator can be changed whenever push/insert or pop/remove occurs.
530 /// <param name="page">The page in Navigator.</param>
531 /// <returns>The index of the given page in Navigator. If the given page is not in the Navigator, then -1 is returned.</returns>
532 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
533 /// <since_tizen> 9 </since_tizen>
534 public int IndexOf(Page page)
538 throw new ArgumentNullException(nameof(page), "page should not be null.");
541 for (int i = 0; i < navigationPages.Count; i++)
543 if (navigationPages[i] == page)
553 /// Inserts a page at the specified index of Navigator.
554 /// The indices of pages in Navigator are basically the order of pushing or inserting to Navigator.
555 /// So a page's index in Navigator can be changed whenever push/insert or pop/remove occurs.
556 /// To find the current index of a page in Navigator, please use IndexOf(page).
557 /// If the page is already in Navigator, then it is not inserted.
559 /// <param name="index">The index of a page in Navigator where the page will be inserted.</param>
560 /// <param name="page">The page to insert to Navigator.</param>
561 /// <exception cref="ArgumentOutOfRangeException">Thrown when the argument index is less than 0, or greater than the number of pages.</exception>
562 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
563 /// <since_tizen> 9 </since_tizen>
564 public void Insert(int index, Page page)
566 if ((index < 0) || (index > navigationPages.Count))
568 throw new ArgumentOutOfRangeException(nameof(index), "index should be greater than or equal to 0, and less than or equal to the number of pages.");
573 throw new ArgumentNullException(nameof(page), "page should not be null.");
576 //Duplicate page is not pushed.
577 if (navigationPages.Contains(page)) return;
579 //TODO: The following transition codes will be replaced with view transition.
580 InitializeAnimation();
582 ShowContentOfPage(page);
584 if (index == PageCount)
586 page.SetVisible(true);
590 page.SetVisible(false);
593 navigationPages.Insert(index, page);
595 page.Navigator = this;
596 if (index == PageCount - 1)
600 NotifyAccessibilityStatesChangeOfPages(navigationPages[PageCount - 2], page);
604 NotifyAccessibilityStatesChangeOfPages(null, page);
610 /// Inserts a page to Navigator before an existing page.
611 /// If the page is already in Navigator, then it is not inserted.
613 /// <param name="before">The existing page, before which a page will be inserted.</param>
614 /// <param name="page">The page to insert to Navigator.</param>
615 /// <exception cref="ArgumentNullException">Thrown when the argument before is null.</exception>
616 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
617 /// <exception cref="ArgumentException">Thrown when the argument before does not exist in Navigator.</exception>
618 /// <since_tizen> 9 </since_tizen>
619 public void InsertBefore(Page before, Page page)
623 throw new ArgumentNullException(nameof(before), "before should not be null.");
628 throw new ArgumentNullException(nameof(page), "page should not be null.");
631 //Find the index of before page.
632 int beforeIndex = navigationPages.FindIndex(x => x == before);
634 //before does not exist in Navigator.
635 if (beforeIndex == -1)
637 throw new ArgumentException("before does not exist in Navigator.", nameof(before));
640 Insert(beforeIndex, page);
644 /// Removes a page from Navigator.
646 /// <param name="page">The page to remove from Navigator.</param>
647 /// <exception cref="ArgumentNullException">Thrown when the argument page is null.</exception>
648 /// <since_tizen> 9 </since_tizen>
649 public void Remove(Page page)
653 throw new ArgumentNullException(nameof(page), "page should not be null.");
656 //TODO: The following transition codes will be replaced with view transition.
657 InitializeAnimation();
659 HideContentOfPage(page);
665 navigationPages[PageCount - 2].SetVisible(true);
666 NotifyAccessibilityStatesChangeOfPages(page, navigationPages[PageCount - 2]);
668 else if (PageCount == 1)
670 NotifyAccessibilityStatesChangeOfPages(page, null);
673 page.Navigator = null;
674 navigationPages.Remove(page);
679 /// Removes a page at the specified index of Navigator.
680 /// The indices of pages in Navigator are basically the order of pushing or inserting to Navigator.
681 /// So a page's index in Navigator can be changed whenever push/insert or pop/remove occurs.
682 /// To find the current index of a page in Navigator, please use IndexOf(page).
684 /// <param name="index">The index of a page in Navigator where the page will be removed.</param>
685 /// <exception cref="ArgumentOutOfRangeException">Thrown when the index is less than 0, or greater than or equal to the number of pages.</exception>
686 /// <since_tizen> 9 </since_tizen>
687 public void RemoveAt(int index)
689 if ((index < 0) || (index >= navigationPages.Count))
691 throw new ArgumentOutOfRangeException(nameof(index), "index should be greater than or equal to 0, and less than the number of pages.");
694 Remove(navigationPages[index]);
698 /// Returns the page at the top of Navigator.
700 /// <returns>The page at the top of Navigator.</returns>
701 /// <since_tizen> 9 </since_tizen>
704 if (navigationPages.Count == 0) return null;
706 return navigationPages[navigationPages.Count - 1];
710 /// Disposes Navigator and all children on it.
712 /// <param name="type">Dispose type.</param>
713 [EditorBrowsable(EditorBrowsableState.Never)]
714 protected override void Dispose(DisposeTypes type)
721 if (type == DisposeTypes.Explicit)
723 foreach (Page page in navigationPages)
725 Utility.Dispose(page);
727 navigationPages.Clear();
731 if (navigatorWindow.TryGetValue(this, out window) == true)
733 navigatorWindow.Remove(this);
734 windowNavigator.Remove(window);
742 /// Returns the default navigator of the given window.
744 /// <returns>The default navigator of the given window.</returns>
745 /// <exception cref="ArgumentNullException">Thrown when the argument window is null.</exception>
746 /// <since_tizen> 9 </since_tizen>
747 public static Navigator GetDefaultNavigator(Window window)
751 throw new ArgumentNullException(nameof(window), "window should not be null.");
754 if (windowNavigator.ContainsKey(window) == true)
756 return windowNavigator[window];
759 var defaultNavigator = new Navigator();
760 defaultNavigator.WidthResizePolicy = ResizePolicyType.FillToParent;
761 defaultNavigator.HeightResizePolicy = ResizePolicyType.FillToParent;
762 window.Add(defaultNavigator);
763 windowNavigator.Add(window, defaultNavigator);
764 navigatorWindow.Add(defaultNavigator, window);
766 return defaultNavigator;
770 /// Create Transitions between currentTopPage and newTopPage
772 /// <param name="currentTopPage">The top page of Navigator.</param>
773 /// <param name="newTopPage">The new top page after transition.</param>
774 /// <param name="pushTransition">True if this transition is for push new page</param>
775 private TransitionSet CreateTransitions(Page currentTopPage, Page newTopPage, bool pushTransition)
777 currentTopPage.SetVisible(true);
778 // Set Content visible because it was hidden by HideContentOfPage.
779 (currentTopPage as ContentPage)?.Content?.SetVisible(true);
781 newTopPage.SetVisible(true);
782 // Set Content visible because it was hidden by HideContentOfPage.
783 (newTopPage as ContentPage)?.Content?.SetVisible(true);
785 List<View> taggedViewsInNewTopPage = new List<View>();
786 RetrieveTaggedViews(taggedViewsInNewTopPage, newTopPage, true);
787 List<View> taggedViewsInCurrentTopPage = new List<View>();
788 RetrieveTaggedViews(taggedViewsInCurrentTopPage, currentTopPage, true);
790 List<KeyValuePair<View, View>> sameTaggedViewPair = new List<KeyValuePair<View, View>>();
791 foreach (View currentTopPageView in taggedViewsInCurrentTopPage)
793 bool findPair = false;
794 foreach (View newTopPageView in taggedViewsInNewTopPage)
796 if ((currentTopPageView.TransitionOptions != null) && (newTopPageView.TransitionOptions != null) &&
797 currentTopPageView.TransitionOptions?.TransitionTag == newTopPageView.TransitionOptions?.TransitionTag)
799 sameTaggedViewPair.Add(new KeyValuePair<View, View>(currentTopPageView, newTopPageView));
806 taggedViewsInNewTopPage.Remove(sameTaggedViewPair[sameTaggedViewPair.Count - 1].Value);
809 foreach (KeyValuePair<View, View> pair in sameTaggedViewPair)
811 taggedViewsInCurrentTopPage.Remove(pair.Key);
814 TransitionSet newTransitionSet = new TransitionSet();
815 foreach (KeyValuePair<View, View> pair in sameTaggedViewPair)
817 TransitionItem pairTransition = transition.CreateTransition(pair.Key, pair.Value, pushTransition);
818 if (pair.Value.TransitionOptions?.TransitionWithChild ?? false)
820 pairTransition.TransitionWithChild = true;
822 newTransitionSet.AddTransition(pairTransition);
825 newTransitionSet.Finished += (object sender, EventArgs e) =>
827 if (newTopPage.Layout != null)
829 newTopPage.Layout.RequestLayout();
831 if (currentTopPage.Layout != null)
833 currentTopPage.Layout.RequestLayout();
835 transitionFinished = true;
836 InvokeTransitionFinished();
837 transitionSet.Dispose();
840 if (!pushTransition || newTopPage is DialogPage == false)
842 View transitionView = (currentTopPage is ContentPage) ? (currentTopPage as ContentPage).Content : (currentTopPage as DialogPage).Content;
843 if (currentTopPage.DisappearingTransition != null && transitionView != null)
845 TransitionItemBase disappearingTransition = currentTopPage.DisappearingTransition.CreateTransition(transitionView, false);
846 disappearingTransition.TransitionWithChild = true;
847 newTransitionSet.AddTransition(disappearingTransition);
851 currentTopPage.SetVisible(false);
854 if (pushTransition || currentTopPage is DialogPage == false)
856 View transitionView = (newTopPage is ContentPage) ? (newTopPage as ContentPage).Content : (newTopPage as DialogPage).Content;
857 if (newTopPage.AppearingTransition != null && transitionView != null)
859 TransitionItemBase appearingTransition = newTopPage.AppearingTransition.CreateTransition(transitionView, true);
860 appearingTransition.TransitionWithChild = true;
861 newTransitionSet.AddTransition(appearingTransition);
865 newTransitionSet.Play();
867 return newTransitionSet;
871 /// Retrieve Tagged Views in the view tree.
873 /// <param name="taggedViews">Returned tagged view list..</param>
874 /// <param name="view">Root View to get tagged child View.</param>
875 /// <param name="isRoot">Flag to check current View is page or not</param>
876 private void RetrieveTaggedViews(List<View> taggedViews, View view, bool isRoot)
878 if (!isRoot && view.TransitionOptions != null)
880 if (!string.IsNullOrEmpty(view.TransitionOptions?.TransitionTag))
882 taggedViews.Add((view as View));
883 if (view.TransitionOptions.TransitionWithChild)
891 foreach (View child in view.Children)
893 RetrieveTaggedViews(taggedViews, child, false);
898 /// Notify accessibility states change of pages.
900 /// <param name="disappearedPage">Disappeared page</param>
901 /// <param name="appearedPage">Appeared page</param>
902 private void NotifyAccessibilityStatesChangeOfPages(Page disappearedPage, Page appearedPage)
904 if (disappearedPage != null)
906 disappearedPage.UnregisterDefaultLabel();
907 //We can call disappearedPage.NotifyAccessibilityStatesChange
908 //To reduce accessibility events, we are using currently highlighted view instead
909 View curHighlightedView = Accessibility.Accessibility.GetCurrentlyHighlightedView();
910 if (curHighlightedView != null)
912 curHighlightedView.NotifyAccessibilityStatesChange(new AccessibilityStates(AccessibilityState.Visible, AccessibilityState.Showing), AccessibilityStatesNotifyMode.Single);
916 if (appearedPage != null)
918 appearedPage.RegisterDefaultLabel();
919 appearedPage.NotifyAccessibilityStatesChange(new AccessibilityStates(AccessibilityState.Visible, AccessibilityState.Showing), AccessibilityStatesNotifyMode.Single);
923 internal void InvokeTransitionFinished()
925 TransitionFinished?.Invoke(this, new EventArgs());
928 //TODO: The following transition codes will be replaced with view transition.
929 private void InitializeAnimation()
931 if (curAnimation != null)
934 curAnimation.Clear();
938 if (newAnimation != null)
941 newAnimation.Clear();
946 // Show and Register Content of Page to Accessibility bridge
947 private void ShowContentOfPage(Page page)
949 View content = (page is DialogPage) ? (page as DialogPage)?.Content : (page as ContentPage)?.Content;
952 content.Show(); // Calls RegisterDefaultLabel()
956 // Hide and Remove Content of Page from Accessibility bridge
957 private void HideContentOfPage(Page page)
959 View content = (page is DialogPage) ? (page as DialogPage)?.Content : (page as ContentPage)?.Content;
962 content.Hide(); // Calls UnregisterDefaultLabel()