Passing Non-Static Objects Between View Controllers - iphone

I'm a newb to iphone development and objective c, but hoping some folks smarter than me can lend a hand. Here's my problem:
I have a view based app with about 7 different view controllers. The user navigates via a bottom tab bar. I have the users entering data in the first view controller to an object named "copies". I need to get the copies value to another controller so it can be used for calculations. This needs to be done for many objects in the apps other controllers too.
Example:
User enters Copies value in 1st view controller.
User enters Price value in 6th view controller.
7th view controller calculates copies x price = grand total
In my research I worked out the singleton method, but that seems limited to static data.
What's the best way to ensure that another view controller can access an object the user has filled in? I'm trying to avoid going a SQLite route currently. I want to stick to something basic and work my way up in complexity. Does anyone have any sample code I can review? It really helps to see how others have tackled this before.
Thanks in advance!

If I've understood you correctly there is just one copies value and one price value in the whole app. If that is the case...
There are many ways to do this. Easiest way (perhaps): you could make a Singleton object of a class that you define that has copies and price as properties. Singleton in Objective-C is here, and you would define your properties within the Singleton class. Then you would just call its shared instance and use the values on that. So your code would look like this:
[ThatCrazySingleton sharedInstance].copies = 5;
for writing.
Hope this is what you're looking for.
If you don't want to use a Singleton, at some point one of the UIViewControllers would need to send a message to the others with the copies and price values (hopefully wrapped up ["encapsulated"] in an object). This means that you have to get a reference to the other View controllers, which you can always do by going through the hierarchy.

Related

Using data between any controller

I have spent hours trying to use a set a tableViewCell from a picker selection in another view. I have posted two questions, that brought no answers. So i decided to approach it differently. I tired making a global variable, but then figured out, I had to make a dataClass file which wouldn't work for me because I have to use a viewController. Im beginning to lose hope. Is their any way to set the title of a table view cell from another view? Im not looking for a giant chunk of code, just a place to start. The way to actually do it, if its possible. Thanks in advance.
Yes, this is definitely possible. In Model-View-Controller systems all information sharing happens through your model class. Make it a singleton object (singleton is similar to global variables, but it has proper initialization).
Create a class with the data that must be shared. Create a class method of that class to produce the sole instance of that class. Define and initialize a static variable holding that instance. Use dispatch_once to initialize that instance. Here is an answer illustrating this approach.
With a singleton instance in place, all your view controllers can access the model as necessary. One view controller can set properties of the model, so that when the other view controller comes along, the data is ready for it to process.

Model-Views-Controller

Yes, I'm a noob at Xcode. right now I'm working my way through the Big Nerd Ranch IOS programming book, and I just need a little clarification on the Model-View-Controller bit.
Model class is called 'CellData', an NSObject
View class 'CellView', a UIView
Controller class is called 'CellAppDelegate', a UIResponder.
The DrawRect method does a lot of drawing, with colors based upon the data from the CellData Class. Everything so far seems tells me that I should not call a 'CellData' method from my 'CellView' class. Normally yeah when your just using UIButtons with TestFields, yeah, makes perfect sense.
In this case, I have up to pass a value from 'CellData' to 'CellView' up to 6000 times to refresh a View. Does it still make sense to keep on calling back and forth between using the CellAppDelegate (seems like a lot more work for the computer), or am I really 'allowed' to retrieve a value from CellData?
You've answered your question yourself really. No, 6000 calls per render isn't the right thing to do, especially on a table view cell which will be redrawn pretty frequently.
Personally, I see the controller's job as asking for data objects from the model layer (where business logic etc happens) and passing them into views. So, in your case, I would just pass the data object into your cell. (I would have it as a property on your cell with a setter that also called [self setNeedsDisplay]; to trigger a redraw)
That being said, I also tend to favour the model layer giving out immutable data objects so the controller / view can't do anything wrong with them :) With this approach, if the controller wanted to edit the data object it would have to call a method in the model layer to do so.
Though, of course, this is just my personal opinion and choice of architecture. And obviously for existing UI objects (i.e. a UILabel etc) I can't pass in the data object, I have to set the text property directly from my view controller.
PS CellAppDelegate is a bad name for a view controller - the custom is to end the class name with ViewController so it would be CellAppViewController. This naming scheme makes it very easy to come back to your code in a week or so and still understand what everything does :)
Everything so far seems tells me that I should not call a 'CellData' method from my 'CellView' class.
This sounds like a misunderstanding. It is extremely common for something like CellView to be handed a single CellData by the controller. The view is free to query the model object it is responsible for displaying. This is not a violation of MVC. It should generally not write to the model object, nor should it talk to other model objects typically.

Passing Several NSStrings to another view - Iphone

In my iPhone app, the user will be making multiple NSStrings. Once these are made, I need to pass them to another view completely in the app. How can i do this? All I know at the moment os I can't access objects or variables declared in one view, in another. Thanks.
One way would be to follow the MVC (model view controller) design pattern. Whichever controllers are responsible for your respective views can then store and retrieve the NSStrings from/to a common data model object.
As to how you can make the strings stored in an object visible to the outside, the easiest way is to use Objective-C properties to save you from writing the accessor methods yourself.
I hope this helps with your problem or at least gets you started in the right direction.
Place the strings in a data model object (the M of the MVC pattern), with accessor methods (getter and setters, which can be automagicly created by properties). Then create and place that model object in some central location, a controller common to all views requiring that data, or the appDelegate, a reference for which can be found from any view.
Josh,
I would add to the MVC thing, that still you can do this in several ways.
What I would do for example, is to make your other "View Controller" (MVC), to "observe" when does the user create a new string, and to fetch it accordingly. In that way you would reduce coupling and it will be a cleaner implementation.
Another way would be to create a "delegate" so that the First View controller, "notifies" or calls the delegate method that you created, each time the user creates a new string ( again reducing coupling )

Having Freudian child parent problems with my objects. Need some pointers and/or Reference?

I think I have a basic question that is sort of hard to look up, I think.
Objective-C for Iphone.
I want to create two view controller instances that message and update an instance of a Model Class. How do you do this? I would prefer no using singletons. It's basically an "I really want to learn from you guys because this is awesome and I want to be awesome too!" question.
I would prefer we keep app delegate, singletons, nsnotification center out of the picture. App delegate specifically in that I dont think I wnat to have my data object created by app delegate, but I may have to.
The way, as I understand it, this works is sort of like this. Navigation Controller creates instance of FirstLevelViewController. My FirstLevelViewController creates instances of my SecondLevelViewControllers and then when told to pushes them onto the navcontroller stack.
I have my Model Instance being created by my firstlevelviewcontroller instance. Is that wrong? I think I need a reference to the instance passed to my secondlevelviewcontroller, but I'm having trouble because I can't figure out what the instance name of the firstlevelviewcontroller is (I think NavController instantiated it).
Help is so very much appreciated.
Assuming the model stays the same object (it can be mutable but not deallocated within the lifetime of BOTH view controllers), one might use a separate variable in each view controller to point to the same model class, with each view controller not knowing about the other. This is of course dependent on your application specific logic -- if one view controller 'knows about' the other than of course it makes sense to have the model be 'owned' but the independent one, and accessible to the dependent one via properties. However this considered bad because it promotes code coupling and dependency, which is looked at as poor coding. As to how both view controllers get the same model instance, typically it would be set (preferably in initialization) by whatever knows about them both, such as a higher level view controller, or if they are root view controllers, the app delegate.

Getting a UIButton to send commands to another View Controller

Question..
I'm currently making a conversion app. I have for the first tab where the information is entered. Views 2 and 3 are where the information from view 1. I'm having an issue.. I'm not sure how to send the information from view 1 to view 2 and 3.
I've looked at examples.. but I'm still not quite grasping the idea of it. any suggestions?
Thanks!
Instead of thinking in terms of sending information between views, create a "model object" that contains all the data that is shared between views, and let controller classes take care of updating the views when the model is changed.
Also, take a look at the documentation for NSNotificationCenter for a way to "broadcast" data updates throughout your app.