I have a basic modal view system.
My app loads the UI base in which there are 2 buttons presenting 2 other views.
In those views, a dismiss button.
Everything works fine.
BUT, in one of the 2 modal views, I have a bunch of UISlider & UISwitch.
I want them to retain their values but the dismiss loses them: as soon as I trigger the button to show the view containing the UI elements, this view is shown with all values for all elements as I put initially in the xib.
should I store all values in variables, then in viewWillAppear I could "recall" them ?
would you advice me another strategy ?
Yes, your proposed approach is exactly the right sort of thing. But be careful; viewWillAppear can be called for many reasons; make sure you're only doing this when the view controller is coming into existence and showing the view for the first time.
NSUserDefaults can be an excellent place to store globally needed info like this. In viewWillDisappear, store the desired state info (values of the sliders and switches) in defaults. Then retrieve them the next time the view is about to appear.
When you create the modal view you are creating a new instance of the modalViewController an the modalView. This new instance knows nothing about any other instance. There are a few ways you can retain the information from previous iterations of these modal view controllers.
How I would do it:
Set up place holders in your main view and pass the values that the user selects back to the main view via a protocol and delegate setup. Then when you segue to the modal view you can load those variables in before displaying the modal view.
So let's say you have a dictionary with all of the values: {slider = YES, someValue=10,...} Create that dictionary in the main view controller, the first one that opens, and place some default values in it.
In your modal view controllers create the same dictionary as a property.
Create a protocol in your modal view controller with a method that is something like
- (void) doneEditing:(NSDictionary *)values
Set up your first view as the delegate for the modal view controller and in the implementation of doneEditing copy the values to the dictionary that is present in the first view before popping the modal view.
When the first view is ready to present the modal view again, copy the values to the dictionary property of the modal view before presenting it.
I hope this gets you headed in the right direction. It's important to remember that each time you segue or create and present a modal view you are creating a brand new instance of that view, it knows nothing about the previous instance at all unless you tell it something about it.
Related
I have two view controller. On the Second controller I have a button which cause a UILabel to change from "larry" to the string "happy". If I press back, which take me to first view controller, and then forward, which take me to the second view controller (from the first view controller). I found that the UILabel change back to default, "larry". How do I make it so that when I change view controller, the changes and data doesn't get clear away.
Recap: How to make it so that every change in a view controller doesn't change back to default after changing to another view controller.
This doesn't only happen with UILable, it also happen with
self.loadPage.hidden = YES;
I also found out what I made to turn 'hidden' also appear back after I pressed back and forward.
Thank
The problem that you are facing is due to the fact that when you press the button a new instance of the second viewcontroller is created and that old one is destroyed.
If you want to persist the data while pressing the buttons, you need some way to store the information somewhere
there are some methods to got about it
You can use instance variables in both the classes to store the data temporarily and display them. You need to know the concept of protocols and delegates for this as well.
You can store the information in NSUserDefaults for some moment so that you can access it later on.
The issue is each time when you goes from first view controller to second, you are initialising a new instance of second view controller which brings back every values you changed to default values.
You need to save the values elsewhere and assign those values whenever control is switched from one view controller to another
I got app with 2 view controllers, I'm typing values via NSStrings in Label and TextField in my first view controller and when I by pushing my navigation button go to my second view controller.
When I return to my first view controller, I got entered early values. But when next after that I go to my second view controller - values entered via NSStrings in Label and TextField disappear. How to fix this that the values saved?
I tried to use strong and copy properties but that not helps me.
UPDATE
I use segue and storyboards, segue with modal type, I use 2 navigation controllers: for first view controller and for second. I got code only for modal type. First view controller is root for navigation
UPDATE
I use 2 navigation controllers because I need modal segue from first VC to second and from second to first, when I use one navigation controllers that is not works like I need
Post some code otherwise we are just guessing. One guess is that you are using segues. Segues always create a new instance of the viewController. If you don't hold on to the old viewController somehow, it will get destroyed and any values it contained are also gone.
Just a guess.
This is probably a very simple question but I can't find the answer to it.
I am working on a new project that uses Storyboards for the first time.
I have a number of view controllers that connect the way I want them to.
Each view controller has an info button.
I have one view controller (AboutViewController) that I want to use to display the info for all the view controllers. I am currently calling this via a popover segue from each screen. So I have one destination view controller (AVC) that I am calling from a number of VCs- VC1toAVC, VC2toAVC, VC3toAVC etc. I want two textfields in AVC to change, depending on which VC called it.
So here's the problem- how can I tell which view controller called the popup? It's basically the view that's below the popover. Currently I'm storing it as a variable but that's not ideal. I'm guessing it has something to do with the segue identifiers?
Any and all help much appreciated!
One approach to this is adding a property to your pop up view controller and then define the
prepareForSegue:sender:
method so you set your destination view controller's property to the sender of the segue.
How can I call individual view controllers when I tap each row from my Pop Over List View in the most effective way? Meaning, I don't have to recode to build the Pop Over List View component in each of the individual view controllers, they can sort of share it like a navigation tool.
What I Have Built
I have built the pop over view controller list on my Main View Controller.
This is the 1st view that gets loaded when appDidFinishLaunching is executed.
So, when we run the app, this is what we get:
Link to screenshot of the Pop Over List View:
http://s14.postimage.org/63k567vtd/image.png
For each row in the above Pop Over list, I have a method where I can put in the codes to:
1. Identify which row was selected
2. Based on the row selected, do any action, like NSLog and stuff
3. All this codes sit in the Main View Controller
The Requirement
I am building a demo app, so all data is dummy data at the moment.
I need to call individual View Controller when each of the row in the Pop Over list is tapped.
Each of the View Controllers, will have their own set of data, own set of UI objects, its own XIB file.
So, if user taps on Applications, it must bring up the Applications XIB file and its functionality, followed by any navigations from here. If Application xib has a button that launches another view, this functionality should be in place too.
However, they all must have the same top Navigation Bar with the Pop Over list button, so user can tap that button and see the Pop Over list anytime in the app.
Please share your view.
Thank you.
I suggest looking in to UISplitViewController. It is a component built by Apple to manage what it looks like you are trying to accomplish. Essentially, you set it up with 2 view controllers; the first (called the "master"), would be your table view. The second (called "detail") would be the view controller that gets switched out.
Once you explore it a little and are comfortable with the terminology, here's the general advice:
Inside the master table view controller's didSelectRowAtIndexPath: method, instantiate the appropriate view controller (based on the indexPath), and set it as the detail view controller, like this:
- (void)tableView:tableView didSelectRowAtIndexPath:indexPath {
UIViewController *newDetailVC = // make and configure a new VC based on indexPath
self.splitViewController.viewControllers = [NSArray arrayWithObjects: self, newDetailVC, nil]];
}
Here are the appropriate links:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UISplitViewController_class/Reference/Reference.html#//apple_ref/occ/cl/UISplitViewController
and further (the later sections of): http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html%23
My root view is a grouped tableview. When the user selects a row, i want to be able to retain which row was selected to give to the detailcontroller for loading the correct data.
All the navigation is working fine, I just don't want to have to create a global variable to just retain the index. Is there a built in method for the navcontroller or something?
You can either set a property in you detail view controller before it is pushed giving info about the row selected so it can influence the behaviour of the detail view controller, or it is possible to access the parent view controller directly from the detail view controller with:
#property(nonatomic, readonly) UIViewController *parentViewController
I prefer the first option - you can write a custom init... method, to supply the data for the detail view controller when it's created.
There isn't a builtin way as such, you should try and make the view controllers de-coupled as possible so they can be re-used and are resistent to changes elsewhere in the app.
This is a useful quote from the View Controller Programming Guide for iOS:
With the exception of view controllers managing leaf data, each custom view controller must provide a way for the user to navigate to the next level of the data hierarchy. A view controller that displays a list of items can use taps in a given table cell to display the next level of data. For example, when a user selects a photo album from the top-level list, the Photos application creates a new photo album view controller. The new view controller is initialized with enough information about the album for it to present the relevant photos.
I wanted to follow up with how I ended up coding this. I'm still somewhat new to Obj-C, so some concepts I haven't dealt with or come across, so if this is old hat, sorry.
You can create your data element in the child controller and pass the data 1 for 1 directly to that element by accessing its property.
ParentController.h
NSDictionary *myData;
ChildController.h
NSDictionary *childData;
// This would get called in the parent controller where appropriate
// but before the child controller is presented
ChildController.childData = myData;
This is obviously very stripped down, but the idea works. Just take your data and pass it to the property before calling it and it will be there once the child view is presented. Hope this helps.