public override IEnumerator LeaveOverlayViewPageBase(ViewSystemUtilitys.OverlayPageStatus overlayPageState, float tweenTimeIfNeed, Action OnComplete, bool ignoreTransition = false, bool ignoreTimeScale = false, bool waitForShowFinish = false) { if (waitForShowFinish && overlayPageState.transition == ViewSystemUtilitys.OverlayPageStatus.Transition.Show) { ViewSystemLog.Log("Leave Overlay Page wait for pervious page"); yield return(new WaitUntil(() => !overlayPageState.IsTransition)); } var currentVe = currentViewPage.viewPageItems.Select(m => m.runtimeViewElement); var currentVs = currentViewState.viewPageItems.Select(m => m.runtimeViewElement); var finishTime = ViewSystemUtilitys.CalculateOnLeaveDuration(overlayPageState.viewPage.viewPageItems.Select(m => m.runtimeViewElement)); overlayPageState.transition = ViewSystemUtilitys.OverlayPageStatus.Transition.Leave; List <ViewPageItem> viewPageItems = new List <ViewPageItem>(); viewPageItems.AddRange(overlayPageState.viewPage.viewPageItems); if (overlayPageState.viewState != null) { viewPageItems.AddRange(overlayPageState.viewState.viewPageItems); } foreach (var item in viewPageItems) { if (item.runtimeViewElement == null) { ViewSystemLog.LogWarning($"ViewElement : {item.viewElement.name} is null in runtime."); continue; } // Unique 的 ViewElement 另外處理借用問題 // 暫時不處理 多個 overlay 之間借用的問題!!! if (item.runtimeViewElement.IsUnique == true && IsPageTransition == false) { if (currentVe.Contains(item.runtimeViewElement)) { //準備自動離場的 ViewElement 目前的頁面正在使用中 所以不要對他操作 try { var vpi = currentViewPage.viewPageItems.FirstOrDefault(m => ReferenceEquals(m.runtimeViewElement, item.runtimeViewElement)); var transformData = vpi.GetCurrentViewElementTransform(breakPointsStatus); if (!string.IsNullOrEmpty(transformData.parentPath)) { vpi.runtimeParent = transformCache.Find(transformData.parentPath); } else { vpi.runtimeParent = currentViewPage.runtimePageRoot; } item.runtimeViewElement.ChangePage(true, vpi.runtimeParent, transformData, item.sortingOrder, tweenTimeIfNeed, 0); ViewSystemLog.LogWarning("ViewElement : " + item.viewElement.name + "Try to back to origin Transfrom parent : " + vpi.runtimeParent.name); } catch { } continue; } if (currentVs.Contains(item.runtimeViewElement)) { //準備自動離場的 ViewElement 目前的頁面正在使用中 所以不要對他操作 try { var vpi = currentViewState.viewPageItems.FirstOrDefault(m => ReferenceEquals(m.runtimeViewElement, item.runtimeViewElement)); var transformData = vpi.GetCurrentViewElementTransform(breakPointsStatus); if (!string.IsNullOrEmpty(transformData.parentPath)) { vpi.runtimeParent = transformCache.Find(transformData.parentPath); } else { vpi.runtimeParent = currentViewPage.runtimePageRoot; } item.runtimeViewElement.ChangePage(true, vpi.runtimeParent, transformData, item.sortingOrder, tweenTimeIfNeed, 0); ViewSystemLog.LogWarning("ViewElement : " + item.runtimeViewElement.name + "Try to back to origin Transfrom parent : " + vpi.runtimeParent.name); } catch { } continue; } } // lastOverlayPageItemDelayOutTimes.TryGetValue(item.runtimeViewElement.name, out float delayOut); item.runtimeViewElement.ChangePage(false, null, null, item.sortingOrder, 0, 0, ignoreTransition); } yield return(runtimePool.RecoveryQueuedViewElement()); //Get Back the Navigation to CurrentPage SetNavigationTarget(currentViewPage); InvokeOnOverlayPageLeave(this, new ViewPageEventArgs(overlayPageState.viewPage, null)); if (ignoreTimeScale) { yield return(Yielders.GetWaitForSecondsRealtime(finishTime)); } else { yield return(Yielders.GetWaitForSeconds(finishTime)); } overlayPageState.IsTransition = false; string OverlayPageStateKey = GetOverlayStateKey(overlayPageState.viewPage); overlayPageStatusDict.Remove(OverlayPageStateKey); OnComplete?.Invoke(); }
public override IEnumerator ChangePageBase(string viewPageName, Action OnStart, Action OnChanged, Action OnComplete, bool ignoreTimeScale) { //取得 ViewPage 物件 // ViewPage nextViewPage; //沒有找到 if (!viewPages.TryGetValue(viewPageName, out nextViewPage)) { ViewSystemLog.LogError("No view page match " + viewPageName + " Found"); ChangePageToCoroutine = null; yield break; } if (nextViewPage.viewPageType == ViewPage.ViewPageType.Overlay) { ViewSystemLog.LogWarning("To shown Page is an Overlay ViewPage use ShowOverlayViewPage() instead method \n current version will redirect to this method automatically, but this behaviour may be changed in future release."); ShowOverlayViewPageBase(nextViewPage, true, OnStart, OnChanged, OnComplete, ignoreTimeScale); ChangePageToCoroutine = null; yield break; } //Prepare runtime page root string viewPageRootName = ViewSystemUtilitys.GetPageRootName(nextViewPage); var pageWrapper = ViewSystemUtilitys.CreatePageTransform(viewPageRootName, rootCanvasTransform, nextViewPage.canvasSortOrder); if (nextViewPage.runtimePageRoot == null) { nextViewPage.runtimePageRoot = pageWrapper.rectTransform; } pageWrapper.safePadding.SetPaddingValue(nextViewPage.edgeValues); //所有檢查都通過開始換頁 //IsPageTransition = true; nextViewState = null; viewStates.TryGetValue(nextViewPage.viewState, out nextViewState); IEnumerable <ViewPageItem> viewItemNextPage = PrepareRuntimeReference(GetAllViewPageItemInViewPage(nextViewPage)); IEnumerable <ViewPageItem> viewItemNextState = GetAllViewPageItemInViewState(nextViewState); List <ViewPageItem> viewItemForNextPage = new List <ViewPageItem>(); // 如果兩個頁面之間的 ViewState 不同的話 才需要更新 ViewState 部分的 RuntimeViewElement if (nextViewState != currentViewState) { viewItemNextState = PrepareRuntimeReference(viewItemNextState); } // All reference preparing is done start do the stuff for change page InvokeOnViewPageChangeStart(this, new ViewPageTrisitionEventArgs(currentViewPage, nextViewPage)); OnStart?.Invoke(); List <ViewElement> viewElementDoesExitsInNextPage = new List <ViewElement>(); var allViewElementForNextPageInViewPage = viewItemNextPage.Select(m => m.runtimeViewElement).ToList(); var allViewElementForNextPageInViewState = viewItemNextState.Select(m => m.runtimeViewElement).ToList(); foreach (var item in currentLiveElementsInViewPage) { //不存在的話就讓他加入應該移除的列表 if (allViewElementForNextPageInViewPage.Contains(item) == false && allViewElementForNextPageInViewState.Contains(item) == false) { //加入該移除的列表 viewElementDoesExitsInNextPage.Add(item); } } currentLiveElementsInViewPage.Clear(); currentLiveElementsInViewPage = allViewElementForNextPageInViewPage; if (nextViewState != currentViewState) { foreach (var item in currentLiveElementsInViewState) { //不存在的話就讓他加入應該移除的列表 if (allViewElementForNextPageInViewState.Contains(item) == false && allViewElementForNextPageInViewPage.Contains(item) == false) { //加入該移除的列表 viewElementDoesExitsInNextPage.Add(item); } } currentLiveElementsInViewState.Clear(); currentLiveElementsInViewState = allViewElementForNextPageInViewState; } //對離場的呼叫改變狀態 foreach (var item in viewElementDoesExitsInNextPage) { item.ChangePage(false, null, null, 0, 0); } float TimeForPerviousPageOnLeave = 0; switch (nextViewPage.viewPageTransitionTimingType) { case ViewPage.ViewPageTransitionTimingType.AfterPervious: //TimeForPerviousPageOnLeave = ViewSystemUtilitys.CalculateOnLeaveDuration(viewItemNextPage.Select(m => m.viewElement), maxClampTime); TimeForPerviousPageOnLeave = nextViewPageWaitTime; break; case ViewPage.ViewPageTransitionTimingType.WithPervious: TimeForPerviousPageOnLeave = 0; break; case ViewPage.ViewPageTransitionTimingType.Custom: TimeForPerviousPageOnLeave = nextViewPage.customPageTransitionWaitTime; break; } // nextViewPageWaitTime = ViewSystemUtilitys.CalculateDelayOutTime(viewItemNextPage); nextViewPageWaitTime = ViewSystemUtilitys.CalculateOnLeaveDuration(viewItemNextPage.Select(m => m.viewElement), maxClampTime); //等上一個頁面的 OnLeave 結束,注意,如果頁面中有大量的 Animator 這裡只能算出預估的結果 並且會限制最長時間為一秒鐘 if (ignoreTimeScale) { yield return(Yielders.GetWaitForSecondsRealtime(TimeForPerviousPageOnLeave)); } else { yield return(Yielders.GetWaitForSeconds(TimeForPerviousPageOnLeave)); } viewItemForNextPage.AddRange(viewItemNextPage); if (viewItemNextState != null) { viewItemForNextPage.AddRange(viewItemNextState); } //對進場的呼叫改變狀態(ViewPage) foreach (var item in viewItemForNextPage.OrderBy(m => m.sortingOrder)) { if (item.runtimeViewElement == null) { ViewSystemLog.LogError($"The runtimeViewElement is null for some reason, ignore this item."); continue; } //套用複寫值 item.runtimeViewElement.ApplyOverrides(item.overrideDatas); item.runtimeViewElement.ApplyEvent(item.eventDatas); var transformData = item.GetCurrentViewElementTransform(breakPointsStatus); if (!string.IsNullOrEmpty(transformData.parentPath)) { item.runtimeParent = transformCache.Find(transformData.parentPath); } else { item.runtimeParent = nextViewPage.runtimePageRoot; } item.runtimeViewElement.ChangePage(true, item.runtimeParent, transformData, item.sortingOrder, item.TweenTime, item.delayIn); } foreach (var item in currentLiveElements.OrderBy(m => m.sortingOrder)) { item.rectTransform.SetAsLastSibling(); } float OnShowAnimationFinish = ViewSystemUtilitys.CalculateOnShowDuration(viewItemNextPage.Select(m => m.runtimeViewElement), maxClampTime); //更新狀態 UpdateCurrentViewStateAndNotifyEvent(nextViewPage); foreach (var item in currentLiveElements) { item.OnChangedPage(); } yield return(runtimePool.RecoveryQueuedViewElement()); OnChanged?.Invoke(); if (ignoreTimeScale) { yield return(Yielders.GetWaitForSecondsRealtime(OnShowAnimationFinish)); } else { //通知事件 yield return(Yielders.GetWaitForSeconds(OnShowAnimationFinish)); } ChangePageToCoroutine = null; //Callback InvokeOnViewPageChangeEnd(this, new ViewPageEventArgs(currentViewPage, lastViewPage)); nextViewPage = null; nextViewState = null; //2019.12.18 due to there may be new Callback be add, change the OnComplete to all is done. OnComplete?.Invoke(); }