C# PresentViewController to a viewcontroller in storyboard - c#

I am creating my first Xamarin-application (C#) in iOS and I am having trouble with navigating in storyboard. All of my tabbar-,navigation- and viewcontrollers are in the storyboard. In almost every viewcontroller, I added a menu (Facebook- and YouTube-style) which slides from the side. From there it has to be possible to return to the first viewcontroller (home) in storyboard. Because the menu is active in almost every controller of my application, I don't use segues (It would be a mess in my storyboard).
So I would want to use PresentViewController(), but when I do this, the page turnes black and doesn't show anything.
homeViewController home = new homeViewController();
PresentViewController(home, true, null);
Does it turn black because PresentViewController expects a XIB-file from the homeViewController? I want the user to stay in the storyboard, so he can continue by segueing through my application.
Does someone has an idea?
Thanks in advance.

Did you create the empty constructor yourself? If so, then its not loading the information from the storyboard, which is why it's black.
To create the controller call this:
var controller = Storyboard.InstantiateViewController("HomeViewController") as UIViewController;
You will also have to open the controller in XCode and set its "Storyboard ID" to "HomeViewController". This is the second tab from the left (I think) in the details pane. The same tab where you change the class.

Related

What is the best approach to create a Visual Studio-like Start Window using ReactiveUI?

I want to make a Start / Welcome / Solution selection window which has similar functionalities to the one used in VS19 / VS22, but I'm not sure how to do it exactly.
For more context, my current StartWindowView has a "Create New Project..." button, which should replace the entire window content with a 2-page project creation wizard.
Page 1 should be "Basic Options" where on the bottom there are "Cancel" and "Next" buttons ("Cancel" goes back to the original StartView and "Next" goes to Page2View).
Page 2 should be "Extra Options" where on the bottom there are "Back" and "Finish" buttons ("Back" goes back to Page1View and "Finish" goes back to the StartView, returning a ProjectModel)
From my understanding, these are the ViewModels I'd have to deal with:
StartWindowViewModel // Main window host (possible router)
StartViewModel // Main project selection view
ProjectCreationViewModel // Possible router for Page1 & Page2
ProjectCreationPage1ViewModel // Basic options
ProjectCreationPage2ViewModel // Extra options
My idea was to use Routing, but I don't know if that's the right approach, since I'm not sure if the data between Page1 and Page2 will be preserved when going back and forth.
Also, the routing examples I saw for ReactiveUI have fixed "Back" and "Next" buttons on the bottom, therefore it makes me think that this might not be the solution for my problem, since pressing the "Create New Project..." button replaces the StartViewModel with the ProjectCreationViewModel, making manual navigation impossible.
I might be completely wrong though. I'm really unsure on how to approach this problem.
EDIT: This is how the VS22 start window looks like:
and this is what happens when you press the button marked in red:
As you can see, the entire window changes the current View.
It's not terribly difficult, just keep an observable collection of your view model stack, and always display the last one (or the first one, it's easier with WPF bindings). Note that I'll be referring to this as a stack, but there is no ObservableStack<> already built for you. Either use an ObservableCollection<> or build your own observable stack.
Then as you need to navigate "into" your wizard (new project, clone a repository, etc), you simply push the new child view model onto the stack. When you need to navigate "out of" your wizard (ie, on Cancel), pop the last view model from the stack.
The last step is to associate your views to view models (using DataTemplate in a high-level resource block, either a global one or a local one in your start page) and then bind your view model stack's top to your main window (the shell that has a ContentControl bound to the top of your stack).

Prism Navigation Not Working In New Window

Edit: Please see my comment below - the code itself seems to be correct (at least the Prism region code) but navigation in the new window instance is still not working.
To start off with, here is the issue I'm having...
I have a main window with a menu bar that switches views in the main window to take the user to different screens. This is all working great.
So I thought today that I would add a 'first time user' screen to handle all the initial setup for the application. This is a new window that will pop up if certain first time properties haven't been set and welcome the new user, get the initial setup complete, etc. I wanted to have navigation on this new window in a new region (just next and back buttons that take the user through the setup).
I thought this would be easy but after 3 hours of floundering and searching the darkest corners of the web I am still very confused - I also looked at Brian Lagunas' Pluralsight videos on MVVM but nothing I have tried to apply is working to setup navigation on the new window.
The content region for the main window is named "ContentRegion" and the content region for the new window is named "SetupRegion".
All views are registered in the bootstrapper like so:
// All views must be registered.
Container.RegisterTypeForNavigation<Home>( "Home" );
Container.RegisterTypeForNavigation<Index>( "Index" );
Container.RegisterTypeForNavigation<Settings>( "Settings" );
Container.RegisterTypeForNavigation<FirstTimeSetupWelcomeScreen>( "WelcomeScreen" );
Container.RegisterTypeForNavigation<FirstTimeSetupScreen2>( "FirstTimeSetupScreen2" );
Here is how the new window is being instantiated currently, from the main window:
public MainWindowViewModel(IRegionManager _regionManager, EventAggregator _eventAggregator)
{
eventAggregator = _eventAggregator;
regionManager = _regionManager;
NavigateCommand = new DelegateCommand<string>(Navigate);
// Set the default view to the home screen
regionManager.RegisterViewWithRegion("ContentRegion", typeof(FirstTimeSetupWelcomeScreen));
// Check to see if program is in first time run or not
if ((ConfigurationManager.GetSection("SaveLocationsGroup/Locations") as IndexLocationsSection).SaveLocation.Location == "")
{
var firstTimeWindow = new FirstTime();
firstTimeWindow.Show();
// Set the default view to the welcome screen on new window
regionManager.RegisterViewWithRegion("SetupRegion", typeof(FirstTimeSetupWelcomeScreen));
}
}
In the XAML for the new window, the content control is setup like this:
<Grid>
<ContentControl prism:RegionManager.RegionName="SetupRegion" />
</Grid>
I have tested by replacing the code in the Navigate command on the main window and having it to navigate to the new user controls, showing them in the main window and that works.
However, in the new window they are not and I can't seem to figure out why. I have also tested to see if the button in the first/default user control view model is firing correctly and it is - for reference, here is that Navigate command code:
private void Navigate(string uri)
{
// WriteLine command to test the button firing
Console.WriteLine(uri);
regionManager.RequestNavigate("SetupRegion", uri);
}
Lastly I've placed the first view inside the main window and it seems to fire correctly, changing the content in the main window - I just can't get it to work or anything to work on the new window at all no matter how I try it. I'm assuming that there is something that I don't know that has to do with either navigation on new instances of windows (aside from the main window) or having to do with containers and new windows but I haven't been able to figure out what. Thank you guys for all of your assistance as always.
It turn out Brian Lagunas has a course on multiple shells I should hopefully be able to use to accomplish what I need. I will attempt to use it.

How can I open page in my Xamarin app without using navigation?

I have a Xamarin Forms application, which has 2 buttons on the toolbar. Currently I'm using FreshMVVM (and it's navigation). I want to load pages without putting them into the navigation. I do not want to have the 'back' button on the toolbar, also I do not want the user return the last page.
Here's how I push a page currently:
CoreMethods.PushPageModel<FirstChoicePageModel>();
I tried to push as a modal, but that way the toolbar buttons does not work until I press back. Should I make new navigation containers and switch to them if I push the buttons?
It's been a little while since I've used FreshMVVM, but if I recall correctly, you have 2 options:
If you want to completly reset the nav stack, you can do CoreMethods.PushPageModelWithNewNavigation<FirstChoicePageModel>();
If you want to keep the nav stack, you can set NavigationPage.SetHasBackButton(this, false); in the code behind of the view.
For both of these options, it may necessary to intercept the back button on Android. In the code behind there is an overrideable method:
protected override bool OnBackButtonPressed()
{
return true; // prevent Xamarin.Forms from processing back button
}
If you want to show a page, but you doesn't want to navigate (change the current page), you can always use Popups.
See this link https://github.com/rotorgames/Rg.Plugins.Popup

How to get a default iOS navigation back button

How can I get the default back button on an iOS UINavigationController? I have the button being added in code, but I want the default style. Is there an Enum of System Images that contains the '<', or is there not really a way, and Ill have to design my own?
Heres the code to make the button:
controller.DetailViewController.NavigationItem.SetLeftBarButtonItem (new UIBarButtonItem(UIBarButtonSystemItem.Stop, (sender, args) => {
controller.DetailViewController.NavigationController.PopViewController(true);
}), true);
Its written in C# using mono touch, and Xamarin.iOS, but I can work on porting Objective-c/Swift code if needed. Im just stuck at this point and can't seem to figure it out at all.
If you push your view controller then you will get default back button with navigation bar. If you don't want to push to push viewController then you need to add it on storyBoard. For pushing the view controller you write the code as
Your_ViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:#"Your_ViewController"];
[self.navigationController pushViewController:viewController animated:YES];

Want to create a UIContoller in a UITabController but with no tab button

I want to display an intro view (tutorial) on my monotouch app that when the user clicks on a button will take them to the main storyboard, which contains a UITabController.
I'm new to monotouch and can't work out how to do this. I'm adding an extra view that's been created to the tab bar controller in the AppDelegate.FinishedLaunching, but this always adds the button to the tab bar.
When the user has clicked the button once I don't want to show the intro page ever again, it's a one time deal (I'll save some value to disk to work this out), so I don't want to just add it to the tab controller.
Incidentally if anyone can show me where monotouch decides that it's going to start with the storyboard please let me know. The only thing I've found is the little start arrow that you drag around in XCode, but what if I have two storyboards and I want to load one based on the user being logged in or something.
You need to create simple entry ViewController with the button (Controller1). The next controller in storyboard will be the tabcontroller (TabController).
Thus you will always has the first entry screen in your application.
If you don't want to show it later than make transition from Controller1 to TabController before it is loaded. For example, override the ViewWillAppear method.
The second approach. Use this code to launch whatever you want view above all your controllers at any time:
UIViewController root= UIApplication.SharedApplication.KeyWindow.RootViewController
UIView myCustomView=new MyCustomView();
root.Add(myCustomView);
//call myCustomView.RemoveFromSuperview() and it will be dismissed

Categories