Custom ViewController objects don't persist through View changes - ios

I have no idea if I'm using the right terminology here, but I'm hoping someone can help - I'm pretty new to iOS Dev and have run into a problem:
I have created a custom class that is used to store an object. It has a bunch of properties and functions, just as an object should. This object is being declared in my ViewController's .h file, and initialised and used throughout the ViewController. The object holds a bunch of information about a test, and takes some measurements in various threads.
The problem I'm facing is that when I load another view (using ECSlidingViewController for the menu) and then return to the view which had the object...it seems to have forgotten the object. The tasks running in the threads are all still running, but that instance of the object seems to be gone.
Is there a way to preserve an instance of the object when changing views so that when I return to the appropriate view, the object is still there and I can still use it?
Thanks!

I'd recommend you to put the objects reference in a transversal class, something like a manager or any other class which you consider appropriate according to your design and most important it needs to be a class that you're completely sure won't be release nor re-created as view controllers are usually when you change from one view controller to the other.
A singleton instance that manages your main logic could be a good option.

Turns out that my menuViewController that was implementing the ECSlidingViewController was recreating the view that contained the object each time I selected the item from the menu. Thanks #rdelmar for pointing this out!
The object was persisting, but in a viewController that was being replaced each time it was selected from the menu and hence the object was unreachable.
I simply implemented this and references to the viewControllers are now being stored in a mutable dictionary and simply recalled when the view is needed, rather than recreating the view. This means that the viewController is being reused and the object is persisting with it.

Related

Xcode recreate UIViewController possible?

Is there a way to "recreate" a UIViewController from within itself. Android SDK 11 added recreate() method to activities. In researching the topic I found this for UI Restoration: UI Restoration
I don't think this is really what I'm looking for.
Basically, my app is a flashcard app which allows the user to retry missed words if they missed any when they finish the deck. In Android it's a simple this.recreate() with missed words stored in SharedPreferences and then reloading the view with the new SharedPreferences field. I have the UserDefaults side of this working. I'm not following if recreating view is possible for iOS. Maybe by segueing out and then back in?
I found this Q&A: stackoverflow link
But I'm not using Navigation Controllers. Just a simple UIViewController.
Thanks for reading!
I presume you want both the view controller's properties and its views to be as before. There's no "magic bullet" for doing that; you just have to do it, yourself.
Now, if your view controller is correctly constructed, its properties automatically dictate its interface. The usual thing, therefore, is just to save off the property values (e.g. in UserDefaults) and later restore them and the interface from that.
It is also possible just to retain the view controller so that you can use it again later, directly. It is, after all, just an ordinary object. This can be a little risky, as the view controller's view is memory-intensive, but there are ways to reduce the amount of memory it occupies.

How to reuse UIObjects from one class to multiple classes using Objective C?

I am trying to programmatically create (without using xib and storyboard) universal application with complicated custom tableview, buttons, etc,,,
Now the problem is I need to create all the objects one time into single class file and reuse it multiple class and multiple device constraints. Please help me and give me good examples for my questions.
I think If I can create reusability methods its reducing app memory and increasing app performance little bit moreover others can easily understand my code.
You should create separate instance of those custom ui objects in different UIViewController as re-using 'same view instance' inside different view controller classes will break the view hierarchy as same ui-instance can only have one superview. So you can't re-use the same custom view instance in multiple places. Better implement the low memory methods and use difference instance inside different container(or UIViewController).
I do not think that this is wise or advisable to do, because I thing that element that will be add to the screen will not take so much time to render and because when screen go off screen it will release all of the element so it won't take much memory. If you have multiple (same) element on one screen, then you would have to have multiple copies of this object so you in any case don't save any cash space.
This approach is reasonable where you change a lot of object of same tip, like cells in UITableView, or ImageView in gallery.... In this case you create one class that contains reusable object and they are not universally created.
But to answer your question.
What you could do is subclass all of your UI object, and initialize them into AppDelegate class as properties
AppDelegate is "universal" class that is always created, and all other classes can have access to it.
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;

What is the proper way of passing data from master to detail view controller?

I'm studying developing for iOS and while building a simple app which loads data from database and shows it as a tableview, I've got some issues which I fail to understand so far.
The master - detail controllers' classes were created by me, not by the XCode template, if this matters.
I try to pass data from master tableview controller to detail
controller. The data is as simple as a couple of strings. I use
segue for this purpose. In prepareForSegue method I do the
following:
if ([segue.identifier isEqualToString: #"DetailsSegue"]) {
DetailsViewController* dvc = (DetailsViewController*)segue.destinationViewController;
NSInteger selectedRow =[self.tableView indexPathForSelectedRow].row;
dvc.nameLabel.text = [NSString stringWithFormat:#"%#",
[[self.entitiesArray objectAtIndex:selectedRow name]];
...
}
The problem here is that dvc.nameLabel is nil. And I guess, that
is possibly because the controller has not been fully created yet.
Well, the dvc pointer is not nil, but I don't see the log in my
init method, so my idea that it was not initialized.
I decided to create an instance variable of DetailsViewController
and in prepareForSegue set it:
dvc->name = [NSString stringWithFormat:#"%#",
[[self.entitiesArray objectAtIndex: selectedRow] name]];
and then I set nameLabel property in viewDidLoad method
And it actually worked! So I guess I wouldn't be able to set instance variable of an unitialized instance. But I did. So what was wrong? And I feel this is not the way people do it,
as to have one more variable that holds the same thing seems
redundant.
So what is the proper way of passing a variable (in my case NSString) using a segue to another controller?
Thank you guys for help
The problem in your code is that you're trying to manipulate the other VCs views. Don't do that. Instead, you should create properties in the destination view controller to hold the data you want to display.
As the other poster said, it makes sense to create a class that contains the data for a record, and pass that. You might have your master view controller's model be an array of these objects. The master would use the data objects to populate a table view. When the user clicked on a row to open a detail view, you'd pass a copy of that data object to the detail view controller in prepareForSegue.
The detail view controller could then edit it if desired, and pass the edited object back to the master view controller if the user saved changes, or simply discard the edited object if the user cancels.
Yes, you could use a singleton to save your data model.
If you want to pass data, you're doing it reasonably. UI elements are not guaranteed to be initialized until the main view of the view controller has finished loading, so a non-UI variable is fairly common.
For a more complex app or one that you expect to grow and maintain, the better approach would be to create a class (or classes) that make up the application's data model. Anything that modifies shared data sends updates to the model and anything that needs to use shared data reads from the model. Among many positive results from that strategy, one is less crosstalk between view controller.

Data management across segues

This is a concept question.
Like many others, I have a parent scene and a child or detail scene. When I click on a specific button in my parent scene, prepare to segue gets called and I pass over a couple of properties. In my detail scene, I gather more information and need to save it for use by the parent. I have seen various methods involving delegates, using singletons, and passing directly back to the parent properties. Here is my question, would it be more correct to store the data in a database in the detail controller, or pass it back to the parent controller to store it? It seems to me that since it was collected in the child, it should be stored there.
Would that be the more correct way of handling it?
For simplicity, say the larger model is an array of custom objects and the detail view presents and edits one of those objects. If you pass a custom object to the detail vc on before the segue, there's no need to "pass it back" later. The parent vc passed that object in the first place, so we know it already has a pointer.
Instead, the parent vc should notice that the work has been done on the object it passed and react accordingly (usually update it's view) This can be done by one of a handful techniques:
just assume something changed and update the view on viewWillAppear
notice the custom object changed via KVO (observing one of its properties)
be notified that the object changed because the detail vc posts an NSNotification
learn that the object changed by arranging to be the delegate of the detail vc
pass the detail vc a block to execute when it updates the custom object
It's hard to say what's better without knowing more about your situation. I can say that simple is usually better, and that favors (1). I can also say that delegates are fine, but often overused.
If you're dealing with more than a few pieces of information, it would likely be much easier in the long run to use Core Data. If, down the road, you decided to add more functionality to the app, or wanted to store different kinds of information, it would take no more than a few extra lines of code to do this.
But from what it sounds like, you have a really simple app, so you should probably be fine just making an instance of your "parent scene" in your "detail scene" and storing whatever values you may have in the "detail scene" into properties that already exist in the "parent scene".
Does that answer your question well enough?

Trouble understanding viewControllers in iOS

I'm new to obj-c/iOS and I'm having trouble understanding conceptually at least viewControllers. I've read a lot of the Apple Doc's, I've even used viewControllers to some extent in xCode, but I still don't quite get what they are, or what are the best ways to use them.
I've been an AS3 dev for many years so my mind works in the context of MovieClips/Sprites and the Display list to get graphics on the screen.
Ok so from my understanding...
A viewController is a kind of class that handles graphics in some
fashion and then allows you to do something with them?? What is it in it's most basic sense?
You seem to add viewControllers to a Window class, which I guess is a bit like
adding a display Object to the Display list?
What is it that a viewController does for you in it's most basic sense?
Are there certain things you definitely can't do with them or shouldn't do
with them?
Do viewControllers need to be connected in some way to the rest of the iOS framework to function (apart from being added to a window).
How exactly do they use data? (I've read up on MVC, I understand that conceptually this is a slightly different question) as I understand it you don't hardcode data into a viewController, so how does a viewController access any static data?
Let's say I just wanted to throw an image up on the screen, exactly what part would the viewController play in that process? is it just something which handles only one small aspect of that process or is it the whole show and handles everything?
Does one viewController handle multiple images? is it like it's term, a "controller" for all the images presented on screen, or does it handle one image at a time?
What is a viewControllers connection to the image(s) it handles? it contains references to them?
I'm using the Sparrow framework which is helping but I would still like to be able to get my head around what viewControllers are so I know how to use them properly.
Ha, I apologise for the above I know it must look like I'm completely confused :) thanks for any advice.
Hope this helps you:
A viewController is a kind of class that handles graphics in some fashion and then allows you to do something with them??
It's the glue between a View (Xib File) and the Data (Could be
CoreData or whatever you're using in the backend). All the UI Elements
you are using in the View you normally define as properties in the
controller to get access to them.
What is it in it's most basic sense?
You seem to add viewControllers to a Window class, which I guess is a bit like adding a display Object to the Display list?
I don't really know AS3 so I cannot compare Display lists with ViewControllers. But basically ViewControllers are there to handle
different types of transitions between the views and accessing
(setting/reading) the data which is displayed in the view.
What is it that a viewController does for you in it's most basic sense?
Like I've written above. Most basic sense they interpret what the user
does on the view and depending on the action of the user changes the
model.
Are there certain things you definitely can't do with them or shouldn't do with them?
It is always hard to keep the border between model and controller.
They are pretty close to each other. So what I normally try is to
delocate all logic stuff (like calculations, database access and so
on) this does more belong into the model part. But of couse you're
using these external classes in the controller.
Do viewControllers need to be connected in some way to the rest of the iOS framework to function (apart from being added to a window).
Well like you already have written the ViewController needs to be
connected to a view. Otherwise it would not make much sense. There are
different subtypes of UIViewController such as UINavigationController
where you probably need to overwrite some other methods to provide the
whole functionality wanted by these special subtypes.
How exactly do they use data? (I've read up on MVC, I understand that conceptually this is a slightly different question) as I understand it you don't hardcode data into a viewController, so how does a viewController access any static data?
There could be different approaches to store the data. Simplest way
would be to have the data directly stored in the UIViewController.
This could be a custom class which is the container of the data. All
changes are directly written into this class and displayed by the
UIViewController. But in most of the cases it makes sense to use
CoreData (Which is responsible for reading/writing the data into a
sqlite database). You could look at CoreData as your model and the
UIViewController gets the data from there and passes the data which
the UIViewController has received from the View back to it.
Let's say I just wanted to throw an image up on the screen, exactly what part would the viewController play in that process? is it just something which handles only one small aspect of that process or is it the whole show and handles everything?
The UIViewController would store an internal Property (UIImageView *)
which is in the Interface Builder connected with the UIImageView you
have created in the Xib file. So over these property you can change
through your Controller the image.
Does one viewController handle multiple images? is it like it's term, a "controller" for all the images presented on screen, or does it handle one image at a time?
Yes, this isn't a big problem. You can have as many images you want.
You just need to have the properties defined in the UIViewController
and linked to the View.
What is a viewControllers connection to the image(s) it handles? it contains references to them?
Yeah, its like a reference to the UIElement. You can then change
whatever property of the UIImageView you want directly from the
UIViewController
Some useful links:
Apple Official ViewController Guide
Apple Official ViewController Basics
You should have a look at Storyboards (U can use them since IOS 5.0)
I recommend you to check:
https://stackoverflow.com/questions/1939/how-to-articles-for-iphone-development-and-objective-c
Here are the answers to your questions:
No, it's doesn't handle graphics. It's the controller of the MVC design pattern. It handles the lifecycle of it's contents (for instance the views) and the data linked with.
A UIViewController is set as a root of an UIWindow. For instance, a UINavigationController is a subclass of UIViewController that stacks UIViewController in order to deal with the navigation.
Response in (1)
Try to be more specific with this question please.
As already commented, it's useful if you use the already built-in components like UINavigationController or UITabBarController.
For instance, you can have the data in instance variables and the display them in the contained UIView.
The UIView attached to your UIViewController will contain an UIImageView. Your UIViewController would have a connection with it in order to whatever changes you need, for instance, changing the image when the user press a button.
It can contain multiple UIViewsand therefore multiple UIImageViews (it's a subclass of UIView)
As commented, they would be contained on an UIImageView and would be linked programmatically or with an IBOutlet.
In a nutshell, a view controller is the controller in the MVC pattern. Please check this link before reading further so you're up to date with this pattern:
http://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
OK, basically a controller manages a collection of views. It also fetches data from your model and sets the state of the views. It's important to note that the views know nothing of your model (your data), and the model knows nothing about your views. A controller also receives events from the views and decides how to change your model accordingly. It is essentially managing the synchronisation between your views and model.
There are technologies that help automate this such as KVO and key value binding. A google search will help you there.
One more thing. No other part of your application should access your views except for the controller. So generally in an application controllers tend to communicate with each other, for example via transitions or the delegate patterns between controllers under a navigation controller. So your application backbone tends to be controllers talking to each other.

Resources