There is a problem , I have one available repose collection ViewController. At the same representation have a button switch to another View. Between the repose organized transitions (navigation controller). Clicking on the back button in the second presentation is called ViewDidAppear is good. But I also have an application has tabBarController. And when you click on the first View on the panel tabBar called again ViewDidAppear. Although he no longer needs to be called . Tell me how can I do so that does not cause tabbar ViewDidAppear. A caused only navigationController? Thank you!
ViewDidAppear will be called every time a ViewController is displayed is shown on the screen.
ViewDidLoad is called only when the View is loaded. So for example, if you present a modal view from a view controller (parent vc), then when the modal is dismissed, the parent vc will NOT have its ViewDidLoad method called. Instead it will have ViewWillAppear and ViewDidApper called only.
Moving the code you only want called once to ViewDidLoad should solve your problem.
Related
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).
I'm having a strange issue, and im pretty much at my wits end trying to work it out.
I have a Conductor which activates and deactivates viewmodels used for editing data, these view models implements screen and use OnDeactivate to ensure that any changes are saved before closing.
However for some reason, OnDeactivate in one of my ViewModels is never called, even tho i can see it being passed to DeactivateItem of the conductor.
To do this have the following in my conductor:
private void SwitchScreen(Screen viewModel)
{
DeactivateItem(ActiveItem, true);
ActivateItem(viewModel);
NotifyOfPropertyChange(() => ProjectActionRegion);
}
public override void DeactivateItem(IScreen item, bool close)
{
base.DeactivateItem(item, close);
NotifyOfPropertyChange(() => ProjectActionRegion);
}
This ensures that when TryClose is called the region is correctly updated. The SwitchScreen is called each time a selection is made on a datagrid, loading the viewmodel. I can see that Deactivate item is called when i change selection, and i can see its passing the correct viewmodel into that method.
However OnDeactivate is still never called, and i have no idea why :/
protected override void OnDeactivate(bool close)
{
System.Windows.Forms.MessageBox.Show("SAVE ME!");
}
Edited to remove incorrect code (the base. was a mistake, this is my actual code)
EDIT:
I've just realized what the difference between the working versions and the broken version is. I have a view/viewmodel that works as a conductor, this works fine. However inside that viewmodel i load a second view/viewmodel that also works as a conductor, this one fails to work, i wonder if it has to do with with being inside another conductor (but not actually handled by that conductor, just loaded into that viewmodel)
For screen life-cycle to function correctly, all of the view models in your view hierarchy must be conducted. You should make your child conductor an active screen of your parent conductor.
You can either do this by making it the active item of the parent conductor, or by using the ConductWith method on the child conductor, passing in a reference to the parent conductor.
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
(I'm using c#/Xamarin, but doubt the issue is specific to that.)
When I add a View Controller and then remove it - it's DidReceiveMemoryWarning is still called (in the Simulator and on real devices), so it can't have been released. I've narrowed it down to this:-
UIViewController vc=(UIViewController)this.Storyboard.InstantiateViewController(identifier);
this.AddChildViewController(vc);
vc.RemoveFromParentViewController();
vc=null;
and calling DidMoveToParentViewController and WillMoveToParentViewController (as described in the docs) doesn't help either:
UIViewController vc=(UIViewController)this.Storyboard.InstantiateViewController(identifier);
this.AddChildViewController(vc);
vc.DidMoveToParentViewController(this);
vc.WillMoveToParentViewController(null);
vc.RemoveFromParentViewController();
vc=null;
then simulate a memory warning and vc DidReceiveMemoryWarning gets called even though there is no reference to it. How is this possible when it's been removed as child controller and there is no reference to it.
(The same is happening when I use a segue set up in a Storyboard to go to a detail view in a UINavigationController, for example, after going "back" to the root controller, the detail controller still gets DidReceiveMemoryWarning messages.
Any help to understand this would be appreciated
UPDATE:
Now the problem I have is with a simple UIViewController embedded in a UINavigationController
I add the navigation controller:
this.nc=(UINavigationController)this.Storyboard.InstantiateViewController("NavigationController");
this.AddChildViewController(this.nc);
this.nc.DidMoveToParentViewController(this);
and remove later (after it's loaded):
this.nc.WillMoveToParentViewController(null);
this.nc.RemoveFromParentViewController();
this.nc=null;
and this all works fine (it's not retained). BUT if I add this simple line in the ViewDidLoad method of the ViewController thats embedded, then the ViewController IS retained!
Console.WriteLine("this.NavigationController={0}",this.NavigationController);
ie, just accessing "this.NavigationController" causes the VC to be retained!
So each time I run it, I get another ViewController retained!
Any ideas?
It could be that your view controller’s initialization method has some side effect causing it to stay alive. A common example would be that it creates an NSTimer object, which retains its target. Go through the methods that are called when the view controller is instantiated from the storyboard and see if anything retains it.
I have an application that consists of a shell, a content control that acts as a region and child content controls that goes into that. When the application loads, it starts in a file load view, and once a file is loaded a new region view is navigated to and appropriate child views. The problem I'm having is getting back to the file load view. I can get it to navigate to the file load view, but IsNavigatedFrom isn't called in the child view's VM, and this is causing problems because the child VM has ConfirmNavigationRequest to make sure that the user actually wants to leave that particular view.
Any ideas?
[edit] The button to go back to the file load view is in the parent content control. I've tried putting it in the child but it causes too much redundancy[/edit]
The IsNavigatedFrom will be called in the object that was used by your "RequestNavigate".
If you called RequestNavigate(view), then you can define IsNavigatedFrom in view.
If you want IsNavigatedFrom called in the ViewModel, then you need a viewmodel-first navigation.