public override void Execute(CallbackActionWaiter callbackActionWaiter, bool animated)
        {
            UINavigationController navigationController = (UINavigationController)HostStack.Host;

            if (Controllers.Count == 1)
            {
                navigationController.PushViewController(Controllers[0].AsViewController(), animated);
            }
            else
            {
                UIViewController[] vcs    = navigationController.ViewControllers;
                UIViewController[] newVcs = new UIViewController[vcs.Length + Controllers.Count];

                for (int i = 0; i < vcs.Length; i++)
                {
                    newVcs[i] = vcs[i];
                }

                for (int i = 0, j = vcs.Length; j < newVcs.Length; ++i, ++j)
                {
                    newVcs[j] = Controllers[i].AsViewController();
                }

                navigationController.SetViewControllers(newVcs, animated);
            }
        }
Beispiel #2
0
        public override void Execute(CallbackActionWaiter callbackActionWaiter, bool animated)
        {
            UIViewController host = Controller.Host;

            var vc = Controller.AsViewController();

            callbackActionWaiter.WaitOne();
            host.PresentViewController(vc, animated, callbackActionWaiter.ReleaseOne);
        }
        public async Task UpdateNavigation(NavigationOperation <TViewModel> navigationOperation, INavigationInProgress navigationInProgress)
        {
            if (navigationOperation.Pushes.Count == 0 && navigationOperation.Pops.Count == 0)
            {
                return;
            }

            var controllersToPush = navigationOperation.Pushes.Select(x => new PushInformation <TViewModel>(_factoryAssociation[x.Screen], x.Instance));

            foreach (var push in navigationOperation.Pushes)
            {
                await push.Instance.GetViewModel("");                 //TODO: add route here
            }

            if (navigationInProgress.IsCancelled)
            {
                Task.Run(async() =>
                {
                    // we wait 10s just in case, shouldn't put too much memory pressure on GC
                    await Task.Delay(10_000);

                    foreach (var push in navigationOperation.Pushes)
                    {
                        push.Instance.ViewModelInstance?.SafeDispose();
                    }
                }).ConfigureAwait(false);
                return;
            }

            navigationInProgress.Commit();
            UIApplication.SharedApplication.InvokeOnMainThread(() =>
            {
                var callbackActionWaiter = new CallbackActionWaiter();
                callbackActionWaiter.WaitOne();
                _navigationStack.EnsureInitialized(_navigationController);

                _navigationStack.ApplyActions(navigationOperation.Pops.Count, controllersToPush, callbackActionWaiter);

                // lines below could be commented if we encounter issues with viewmodel disposing
                callbackActionWaiter.Add(() =>
                {
                    foreach (PopAction <TViewModel> pop in navigationOperation.Pops)
                    {
                        pop.Instance.ViewModelInstance?.DispatchSafeDispose();
                    }
                });

                Task.Run(async() =>
                {
                    // we wait 10s to let the time for navigation controller animations before disposing content
                    await Task.Delay(10_000);
                    UIApplication.SharedApplication.InvokeOnMainThread(callbackActionWaiter.ReleaseOne);
                });
            });
        }
Beispiel #4
0
        public override void Execute(CallbackActionWaiter callbackActionWaiter, bool animated)
        {
            var navigationController = (UINavigationController)Pop.HostStack.Host;
            var vcs = navigationController.ViewControllers;

            UIViewController[] newVcs;
            var controllersToDispose = new List <UIViewController>(Pop.CountToPop);

            int newCount = vcs.Length - Pop.CountToPop + Push.Controllers.Count;

            if (vcs.Length == newCount)
            {
                newVcs = vcs;

                for (int j = vcs.Length - Pop.CountToPop; j < vcs.Length; ++j)
                {
                    controllersToDispose.Add(newVcs[j]);
                }
            }
            else
            {
                newVcs = new UIViewController[vcs.Length - Pop.CountToPop + Push.Controllers.Count];

                int copyCount = vcs.Length - Pop.CountToPop;
                for (int i = 0; i < copyCount; ++i)
                {
                    newVcs[i] = vcs[i];
                }

                for (int j = copyCount; j < vcs.Length; ++j)
                {
                    controllersToDispose.Add(vcs[j]);
                }
            }

            for (int i = 0, j = vcs.Length - Pop.CountToPop; j < newVcs.Length; ++i, ++j)
            {
                newVcs[j] = Push.Controllers[i].AsViewController();
            }

            navigationController.SetViewControllers(newVcs, animated);

            callbackActionWaiter.Add(() =>
            {
                foreach (UIViewController controller in controllersToDispose)
                {
                    controller.SafeDispose();
                }
            });
        }
Beispiel #5
0
 public override void Execute(CallbackActionWaiter callbackActionWaiter, bool animated)
 {
     if (HostStack.Modal is NavigationControllerInnerStack navigationControllerInnerStack)
     {
         callbackActionWaiter.WaitOne();
         navigationControllerInnerStack.Host.DismissViewController(animated, callbackActionWaiter.ReleaseOne);
         callbackActionWaiter.Add(() => navigationControllerInnerStack.Host.SafeDispose());
     }
     else if (HostStack.Modal is SimpleControllerInnerStack simpleControllerInnerStack)
     {
         callbackActionWaiter.WaitOne();
         simpleControllerInnerStack.Controller.DismissViewController(animated, callbackActionWaiter.ReleaseOne);
         callbackActionWaiter.Add(() => simpleControllerInnerStack.Controller.SafeDispose());
     }
     else
     {
         throw new NotSupportedException($"Unsupported type of {HostStack.Modal.GetType().Name}");
     }
 }
Beispiel #6
0
        public override void Execute(CallbackActionWaiter callbackActionWaiter, bool animated)
        {
            UINavigationController  navigationController = (UINavigationController)HostStack.Host;
            List <UIViewController> vcs = navigationController.ViewControllers.ToList();

            if (CountToPop == 1)
            {
                UIViewController poppedViewController = vcs[vcs.Count - 1];
                callbackActionWaiter.Add(() => poppedViewController.SafeDispose());
                navigationController.PopViewController(animated);
            }
            else
            {
                int popToIndex = vcs.Count - 1 - CountToPop;
                navigationController.PopToViewController(vcs[popToIndex], animated);
                callbackActionWaiter.Add(() =>
                {
                    for (int i = popToIndex + 1; i < vcs.Count; ++i)
                    {
                        vcs[i].SafeDispose();
                    }
                });
            }
        }
        public void ApplyActions(int popsCount, IEnumerable <PushInformation <TViewModel> > pushesCount, CallbackActionWaiter callbackActionWaiter)
        {
            var pops   = Pop(popsCount);
            var pushes = Push(pushesCount);
            MergedPopPushOperation mergedOp = null;

            if (pops.Count > 0 && pushes.Count > 0 && TryMerge(pops[pops.Count - 1], pushes[0], out mergedOp))
            {
                pops.RemoveAt(pops.Count - 1);
                pushes.RemoveAt(0);
            }

            int  popAnimatedIndex  = mergedOp is null && pushes.Count == 0 ? pops.Count - 1 : -1;
            bool mergedAnimated    = pushes.Count == 0;
            int  pushAnimatedIndex = pushes.Count - 1;

            for (var index = 0; index < pops.Count; index++)
            {
                pops[index].Execute(callbackActionWaiter, popAnimatedIndex == index);
            }

            mergedOp?.Execute(callbackActionWaiter, mergedAnimated);

            for (var index = 0; index < pushes.Count; index++)
            {
                pushes[index].Execute(callbackActionWaiter, pushAnimatedIndex == index);
            }

            Console.WriteLine("apply actions");
        }
Beispiel #8
0
 public abstract void Execute(CallbackActionWaiter callbackActionWaiter, bool animated);