Push more than 3 ViewController in NavigationController from AppDelegate App crash - ios

I am working on Push Notification. Now When the Application is raise to Device and When I Tap on it. I want to push 3 ViewController to Navigation Stack.
So I am using below code to do this.
AppDelegate.cs Code
Window = new UIWindow(UIScreen.MainScreen.Bounds);
Menu = new SlideoutNavigationController();
var storyboard = UIStoryboard.FromName("Main", null);
var webController = storyboard.InstantiateViewController("DashBoardViewController") as DashBoardViewController;
Menu.MainViewController = new MainNavigationController(webController, Menu);
Menu.MenuViewController = new MenuNavigationController(new DummyControllerLeft(), Menu) { NavigationBarHidden = false };
Window.RootViewController = Menu;
Window.MakeKeyAndVisible();
var storyboarddd = UIStoryboard.FromName("Main", null);
var webControllerdd = storyboarddd.InstantiateViewController("DashBoardViewController") as DashBoardViewController;
webControllerdd.reloadNotication();
UINavigationController nav = webController.NavigationController;
var notifyWebController = storyboard.InstantiateViewController("NotificationListViewController") as NotificationListViewController;
notifyWebController.navigationContoller = nav;
nav.PushViewController(notifyWebController, true);
if (type.Equals("Damage Report"))
{
var webController2 = storyboard.InstantiateViewController("DamageReportViewController") as DamageReportViewController;
webController2.DamageReportId = id;
webController2.navigationContoller = nav;
nav.PushViewController(webController2, true);
}
if (type.Equals("Overloss"))
{
var webController2 = storyboard.InstantiateViewController("OverlossViewController") as OverlossViewController;
webController2.PacketId = id;
webController2.navigationContoller = nav;
nav.PushViewController(webController2, true);
}
The upper code is working fine to open Specific ViewController.
But My App crash after it with the crash Log.
Crash Report :
2017-07-26 15:25:18.330 Aastha.iOS[6357:2021514] nested push animation can result in corrupted navigation bar
2017-07-26 15:25:18.740 Aastha.iOS[6357:2021514] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
My Solution :
When i search on google and SO someone says that Open ViewController one after another from each ViewController ViewDidAppear method but I am not sure If this is correct way.
Any Help be Appreciated.

You can't push more than one view controller with animation. If you want user to see transtions A -> B -> C you indeed have to do it in A's and B's viewDidAppear method.
If you want user to only see the last view controller C and be able to go back through A and B, you can push them all at once, but you need to do it without animation:
nav.PushViewController(webController2, false);
Another option is to use SetViewControllers like this:
nav.SetViewControllers([A, B, C], true);
this will push all 3 view controllers at the same time and only the topmost one will be animated using push transition. I don't think this fits your situation, just adding it here for completeness sake.

Related

ios 13 Navigation Controls disappears while sliding down the picker in the CNContactViewController for adding Profile picture?

After clicking on AddPhoto
Observe while slidingdown controller cancel, newcontact and done disappears.
var contact = new CNMutableContact
{
// Given and family names.
FamilyName = participant.LastName,
GivenName = participant.FirstName,
//Note = participant.Note,
OrganizationName = participant.Company,
};
if (!string.IsNullOrEmpty(participant.IconUrl))
{
NSUrl url = new NSUrl(participant.IconUrl);
UIImage image = UIImage.LoadFromData(NSData.FromUrl(url));
NSData data = image.AsPNG();
contact.ImageData = data;
}
var contactViewController = CNContactViewController.FromNewContact(contact);
contactViewController.Delegate = this;
In this section we add the contact with the existing data.
And then adding the contactview controller as a present view controller.
var nc = new UINavigationController(contactViewController);
this.PresentViewController(nc, true, () => {
});
Assuming you are running this on a later version that IOS 8 , Swift now has the ability to enable disable scrolling of the navigation bar view . (If we are talking about the same thing.) . I thinkn the problem lies in your navigation controller instead of the above code .
You can use
self.navigationController?.hidesBarsOnSwipe = false
to disable the hiding of the navigation bar on scrolling and swipping , although This requires that your ViewController is embedded in a NavigationController. All child VC of the NavigationController will inherit this behaviour, so you might want to enable/disable it in viewWillAppear.
You could also disable this in your storyboard by setting the navigation controller -> shownavigationbar

IOS ContactUI navigate back to app after edit

In my Xamarin IOS app I open the ContactUI with the following code:
var contact = new AddressBookService().GetCNContactById(addressbookId);
var view = CNContactViewController.FromNewContact(contact);
view.Editing = true;
// Display the view
var window = UIApplication.SharedApplication.KeyWindow;
var vc = window.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}
var navController = vc as UINavigationController;
if (navController != null)
{
vc = navController.ViewControllers.Last();
}
vc.PresentViewController(new UINavigationController(view), true, null);
I wrap it in a INavigationController because without it won't load. There is the following message printed to the output:
[CNUI ERROR] Contact view delayed appearance timed out
The Edit Dialog is displayed correctly. But after I click on Save I come to the details view:
As you can see is the second problem, that there is no back button. So the only way to come back to my app is to kill the app and start again.
Is there a way to navigate directly back to my app after I saved the contact? Or to wrap the ContactUI in my current ViewController so that the TabBar is still visible below?
Implement the CNContactViewControllerDelegate and use the DidComplete delegate of CNContactViewController. DidComplete will be fired when the "Done" button is clicked.
Set the delegate:
var view = CNContactViewController.FromNewContact(contact);
view.Delegate = new MyCNConatactViewControllerDelegate();
Implement the DidComplete, and dismiss the NavigationController which contains your CNContactViewController here:
public class MyCNConatactViewControllerDelegate : CNContactViewControllerDelegate
{
public override void DidComplete(CNContactViewController viewController, CNContact contact)
{
viewController.NavigationController.DismissViewController(true, null);
}
}

MonoTouch.Dialog with UISplitViewController

I'm creating universal app with MonoTouch. When running on iPad I use UISplitViewController and build multi level menu in master view (on the left side) with MonoTouch.Dialog.
Problem is, that when I touch first root element it opens new view which covers whole screen instead of being inside master split view.
Question is, how can I make so next root element opens inside same view as it's parent?
All the examples I could find usually has one level menu on the master view so when you touch it displays something on the detail view.
Hope this makes sense.
Let's say you have an UISplitViewController and your CustomViewController.
UISplitViewController split = ...;
CustomViewController controller = ...;
If you want to push the new controller on top of the current (master) one then use:
var root = new RootElement ();
var dvc = new DialogViewController (UITableViewStyle.Plain, root, true);
dvc.ActivateController (controller);
If you want to show the new controller in the details (right) section then use something like:
UISplitViewController split = ...;
var about = new StringElement ("About");
about.Tapped += delegate {
split.ViewControllers = new UIViewController [] {
split.ViewControllers [0],
controller
};
};
So you want your, I guess table, in the master to populate a new masterview on touch event?
I'm not familiar with .dialog but i've given an example as i know it:
take your rootviewcontroller.parentviewcontroller.splitviewcontroller and then populate the viewcontrollers[0]
var split =(uisplitviewcontroller)rootviewcontroller.parentviewcontroller.splitviewcontroller;
var nav = (uinavigationcontroller)split.viewcontrollers[0];
nav.pushviewcontroller(_yourView_);

ViewDidAppear on a UINavigationController not getting called when navigating back

I have a UITabBarController that hosts 5 UINavigationControllers (let's call them N1 - N5). Each of the UINavigationControllers has UI elements that cause a UITableViewController to be pushed onto the navigation stack (I use MonoTouch.Dialog DialogViewController to implement these UITableViewControllers). Let's call those T1 - T5.
When I navigate between the tabs, the ViewDidAppear method gets called on each of N1 - N5 as expected. But when I touch a UI element on, say, N1, that causes T1 to get pushed onto the nav stack, and then try to go back using the back button, N1's ViewDidAppear method doesn't get called.
The funny thing is that if I "tab over" to a different tab (say N2) and then "tab back" to N1, the ViewDidAppear will be called as normal. And even if I have T1 pushed onto the nav stack, if I do the same tabbing around, N1's ViewDidAppear will still be called.
The MonoTouch code for N1 looks like this:
public class CalendarPage : UINavigationController
{
private DialogViewController dvc;
public override void ViewDidAppear (bool animated)
{
// initialize controls
var now = DateTime.Today;
var root = new RootElement("Calendar")
{
from it in App.ViewModel.Items
where it.Due != null && it.Due >= now
orderby it.Due ascending
group it by it.Due into g
select new Section (((DateTime) g.Key).ToString("d"))
{
from hs in g
select (Element) new StringElement (((DateTime) hs.Due).ToString("d"),
delegate
{
ItemPage itemPage = new ItemPage(this, hs);
itemPage.PushViewController();
})
{
Value = hs.Name
}
}
};
if (dvc == null)
{
// create and push the dialog view onto the nav stack
dvc = new DialogViewController(UITableViewStyle.Plain, root);
dvc.NavigationItem.HidesBackButton = true;
dvc.Title = NSBundle.MainBundle.LocalizedString ("Calendar", "Calendar");
this.PushViewController(dvc, false);
}
else
{
// refresh the dialog view controller with the new root
var oldroot = dvc.Root;
dvc.Root = root;
oldroot.Dispose();
dvc.ReloadData();
}
base.ViewDidAppear (animated);
}
}
I figured out what was going on. When the back button is pressed on the inner DialogViewController (created in ItemPage), the outer DialogViewController ("T1" above) is now the first responder, NOT the UINavigationController ("N1"). My confusion stemmed from the fact that I turned the back button off on that outer DialogViewController so I was assuming I had popped out all the way to the UINavigationController (N1), whereas I was still in a DialogViewController (T1).
I implemented the desired behavior (refreshing the contents of "T1") by creating a ViewDissapearing event on the inner DialogViewController (ItemPage in this case) and checking whether I am popping out - and if so, invoking the parent controller's ViewDidAppear method.
actionsViewController.ViewDissapearing += (sender, e) =>
{
if (actionsViewController.IsMovingFromParentViewController)
controller.ViewDidAppear(false);
};
Note the funny thing about this code is that the property that actually works is IsMovingFromParentViewController, NOT IsMovingToParentViewController (which is intuitively what you'd think would be set when you're navigating back). I imagine this may be a bug in MT.Dialog, but something that can't be fixed for back-compact reasons.
I hope this ends up helping someone...

Monotouch back to first ViewController

I'm having a problem going back again to my first Apps VC, the first "screen/ViewController)" is a login screen, then I call a UITabbar with their respective ViewControllers, when I'm on a certain level of a ViewController (for example the 5th one) I want to get a "Logout" behavior in my App and get back to the first ViewController (Login). But I think I can only Navigate back to the first ViewController of my Tabbar control. I was trying with this methods of my VC:
this.NavigationController.PopToViewController(previousVC,true);
or
this.NavigationController.PopToRootViewController(true);
Any help would be appreciated.
(If you need more details with the code please tell me about it)
//Call to the tab bar from the login viewcontroller
mainTBC = new TabBarMenuPpal ();
this.NavigationController.PushViewController (mainTBC, true);
…
//Tabbarmenuppal with a set of navcontrollers
public TabBarMenuPpal ()
{
var customerVC = new Customers ();
navCustomers = new UINavigationController ();
navCustomers.PushViewController (customerVC, true);
navCustomers.TopViewController.Title = customersTitle;
navCustomers.TabBarItem = new UITabBarItem (customersTitle, UIImage.FromFile ("Utility/Images/Cust-30x30.png"), 0);
…
mainVC = new UIViewController[]
{
navCustomers
, navSettings
} ;
this.ViewControllers = mainVC;
}
The problem is that when I start to navigate in the navCustomers I can't find a way to go back to the login VC (deleting my tab bar and releasing all their resources). (Sorry about my English).
I don't know if it's the best solution but I have implemented a "GoToLogin" method in my UITabBarController which only does this:
public void GoToLogin()
{
this.NavigationController.PopToRootViewController(true);
}
So when I need to go to my first page I only do this:
if(MainDialog.NavigationController.TabBarController != null)//loaded from the tab bar
((TabBarMenuPpal)MainDialog.NavigationController.TabBarController).GoToLogin();
else//loaded from the login screen
MainDialog.NavigationController.PopToRootViewController(true);

Resources