I am using the Flyout navigation component in my Xamarin IOS application and I am able to connect multiple view controllers to it and also swipe out left and able to see the menu items. But I am not getting a menu indicator at the top as like in the drawer menu applications(like facebook and many android apps). Here is the code I used
FlyoutNavigationController navController = new FlyoutNavigationController {//this will create a new instance of the FlyoutComponent
NavigationRoot = new RootElement("Menu"){ //Here we create the root of the alements
new Section("Seccion 1"){
new StringElement("Picks"),
new StringElement("Watchlist"),
},
new Section("Seccion 2"){
new StringElement("Portfolio"),
},
},
ViewControllers = new [] {//here we link Controllers
this.Storyboard.InstantiateViewController("Picks") as UIViewController,//here we create the instances for the Controllers
this.Storyboard.InstantiateViewController("Watchlist") as UIViewController,
this.Storyboard.InstantiateViewController("Portfolio") as UIViewController,
}
};
//navController.ToggleMenu();
View.AddSubview (navController.View);
Finally I figured out that I have to set the left bar button item with an image looking like a drawer menu like this
UIBarButtonItem menuIndicator = new UIBarButtonItem (UIImage.FromBundle ("images/slideout.png"), UIBarButtonItemStyle.Plain, (sender, e) => {
AppDelegate.FlyoutNavigation.ToggleMenu ();
});
NavigationItem.SetLeftBarButtonItem (menuIndicator, false);
Related
In short I have a SplitViewController as RootController.
And in constructor I've added master and detail controllers.
Detail Controller is wrapped into Navigation Controller.
{
_masterViewController = new MenuViewController();
_inventories = new InventoriesViewController();
_detailNavigationController = new UINavigationController(_inventories);
ViewControllers = new UIViewController[] {
_masterViewController,
_detailNavigationController
};
What are the ways I can show the Menu (show master) back button on details Navigation Bar?
We don't use storyboards
add the following code in the method ViewDidLoad()
UIButton backButton = new UIButton();
backButton.Frame = new CGRect(0,0,20,20);
backButton.SetTitle("Back", UIControlState.Normal);
backButton.SetTitleColor(UIColor.Gray, UIControlState.Normal);
backButton.SetImage(new UIImage("back"), UIControlState.Normal);
//backButton.SetImage(new UIImage("001.jpg"), UIControlState.Normal);
backButton.TouchUpInside += (sender, e) =>
{
NavigationController.PopViewController(true);
};
UIBarButtonItem backItem = new UIBarButtonItem(backButton);
NavigationItem.LeftBarButtonItem = backItem;
After some time I found the property on the UISplitViewController
DisplayModeButtonItem
So after creation of master and detail controller (detail controller is wrapped into UINavigationController) I added the DisplayModeButtonItem into NavigationBar LeftItem of detailed controller. It gave me the desired look and behaviour
{
_masterViewController = new MenuViewController();
_inventories = new InventoriesViewController();
_inventoriesNavigation = new UINavigationController(_inventories);
_inventories.NavigationItem.LeftBarButtonItem = DisplayModeButtonItem;
ViewControllers = new UIViewController[] {
_masterViewController,
_inventoriesNavigation
};
}
We are using MvvmCross 4.4.0 on the our iOS project and I faced the following problem:
I need to implement "Item" page with reference to the other
"Item" page;
I need an instant back navigation from any "Item" page to the previous controller ("Catalogue" controller).
Diagram:
Catalogue --ConcreteItem--> Item1 --MoreItems--> Item2 --MoreItems-->
Item3 --BackNavButton--> Catalogue.
I am doing the following thing in the Custom ViewPresenter:
var topViewController = ParentRootViewController.TopViewController;
ParentRootViewController.PushViewController(currentViewController, needAnimation);
if (topViewController.GetType() == currentView.GetType()
&& /*Logic to determine if its correct view types*/)
{
topViewController.RemoveFromParentViewController();
topViewController.Dispose();
}
And actually it works until I didn't return to the "Catalogue" page.
The problem is that I need to click back button so many times I had clicked "More" button on "Item" page. Also if we use custom back button with such code in both "Catalogue" and "Item" pages:
if (NavigationController?.NavigationBar?.BackItem != null)
{
var backbutton = new UIBarButtonItem(" ",
UIBarButtonItemStyle.Plain,
(sender, e) => { NavigationController?.PopViewController(true); })
{
Image = UIImage.FromBundle("BackButtonImage")
};
NavigationItem.LeftBarButtonItem = backbutton;
}
then app crashes when clicking "Back" NavButton on "Catalogue" page with in lambda
(sender, e) => { NavigationController?.PopViewController(true);
The disposed object ItemPageViewController.
The question is : How to correctly implement "SingleTop" page in MvvmCross?
Or
How to fix this problem?
P.S.: If from MvxPresenter remove line
topViewController.Dispose();
then in custom lambda would throw NullReferenceException.
P.P.S.: I believe it the problem that I don't remove controller from navigation stack. I have tried to remove controllers in Custom View Presenter, but, firstly, it is null there sometimes, and even with null check nothing helped.
UINavigationController has a function PopToViewController(UIViewController viewController, bool animated);
Instead of removing every ViewController when the views are of the same type, you could pop to the ViewController Catalogue when the backbutton is pressed.
UINavigationController has a property ViewControllers that we can use to find CatalogueViewController.
Since you're using MvvmCross we'll check for the ViewModel type.
var catalogueController = NavigationController.ViewControllers.First(c =>
((IMvxIosView)c).ViewModel.GetType() == typeof(CatalogueViewModel));
Now you can use the function PopToViewController to close all the views untill CatalogueController
CurrentNavigationController.PopToViewController(catalogueController, true);
Is it possible such that I can have a navigation controller in each of my tabs of a TabBarController while using Xamarin iOS? I've currently setup my storyboard like so (for simplicity, I'm using a single tab)
TabBarController -> NavigationController -> UITableViewController
In my UITableViewController, the following code in my ViewDidLoad method does not change the title nor add the desired button to the top navigation. Have I set up something wrong?
public override void ViewDidLoad()
{
base.ViewDidLoad();
Console.WriteLine("view did load");
Title = "My custom title";
NavigationItem.SetRightBarButtonItem(
new UIBarButtonItem(UIBarButtonSystemItem.Add, (sender, args) =>
{
PerformSegue("CreateRecordSegue", this);
})
, true);
}
Image of storyboard is here: https://ibb.co/m7qq85
The solution is to:
1) Remove the navigation controller that leads into the tab bar controller
2) Create a segue from the home page into the tab bar controller, making the segue type to replace (instead of push)
Following is the navigation stack I have in my app
page 1 (forms)-> Page 2(Native IOS with Page renderer) -> Another IOS native view via UINavigationController (to select an image from photo galary & process it)-> Page 3 (forms)
Here is what I am trying to do:
Page 1 in forms: Click on a button
Page 2 in IOS using page renderer
Code:
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
var page = e.NewElement as DummyPage;
AppDelegate.DummyPageRef = page;
var view = NativeView;
// create a new window instance based on the screen size
window = new UIWindow(UIScreen.MainScreen.Bounds);
viewController = new ImageViewController();
navigationController = new UINavigationController();
navigationController.PushViewController(viewController, false);
// If you have defined a view, add it here:
//window.AddSubview(navigationController.View);
window.RootViewController = navigationController;
// make the window visible
window.MakeKeyAndVisible();
//var label = new UILabel(new CGRect(0, 40, 320, 40));
//label.Text = "2 " + page.Heading;
//view.Add(label);
}
ImageViewController page in IOS opens a galary for user to select an image, processes the selected image & when done processing calls page 3 on Forms with following
Code:
var secondViewController = App.GoToPostScanPage().CreateViewController();
NavigationController.PushViewController(secondViewController, true);
This works fine. But when I see the page 3 on forms the backstack is still pointing to my dynamic page that I created to select & process the image. How can I get rid of this IOS navigation stack & jump back to my Forms Navigation stack? Is this possible?
Thanks
Supreet
I have a view where I'm letting a user edit a EntryElement. I register the click event fine through the delegate of the "Done" button however, I can't get it to dismiss the current view to go to the previous view though. Here's what I'm trying right now:
AppDelegate.navigation.PresentedViewController.DismissViewController(true, null);
I've also tried:
AppDelegate.navigation.PresentedViewController.RemoveFromParentViewController();
navigation is just a UINavigationController
EDIT:
I am using Monotouch.Dialog to build out all of the views. This view is created via a method. I want it to go back to the previous view once they click the done button. Here's the contents of the method:
public static void EditClientTypeView (string typeName, string typeId)
{
DialogViewController editClientTypeVC;
UIBarButtonItem doneButton = new UIBarButtonItem (UIBarButtonSystemItem.Done);
EntryElement element = new EntryElement("Type Name", "Name of client type", typeName, false);
var root = new RootElement ("Edit Type") {
new Section () {
element
}
};
editClientTypeVC = new DialogViewController (root, true);
editClientTypeVC.NavigationItem.RightBarButtonItem = doneButton;
doneButton.Clicked += (sender, e) => {
// Need to save the edited client type to the database
Console.WriteLine("Done button clicked signifying the user is finished editing");
AppDelegate.navigation.PresentedViewController.RemoveFromParentViewController();
//AppDelegate.navigation.DismissViewController(true, null);
};
AppDelegate.navigation.PushViewController(editClientTypeVC, true);
}
Any help is appreciated!
Since you are PUSHING a view controller onto the Navigation Stack, you dismiss it by POPPING it off the stack. UINavigationController has three POP methods
PopToRootViewController - goes all the way back to the root view of your navigation controller
PopToViewController - pops back to a specific view controller
PopViewController - pops back to the "previous" view controller