Can Objects Call the Main Application? - iphone

Please bear with me, this is probably a very simple problem for an expert but I'm new to the language.
I'm trying to create an application that dynamically generates and releases a series of views, which are displayed in the main window. The problem I am having is in swapping between them. I want each view to contain buttons that cause the view to change. I can make a view close itself, but I don't know how to order the main program to change its own view to something new once that's been done (i.e. message the main application from within one of its child objects). I suppose I could make the main view of the application into a global, but I'd rather be able to contact the main application directly as this strikes me as being somewhat neater and less prone to other problems. Problem is, I don't know the main app's identifier. The convenient 'self' identifier gets used so often that I've never seen a code snippet that contains an identifier for the main application that could be called from outside it. It would also be useful to be able to link NIB file objects directly to attributes held in common by the main program.
Am I going about this in entirely the wrong way? Is there a generic 'main app' identifier? Is it possible to create one, if one isn't generated automatically?
-Ash

Assuming that by 'main application' you mean your app delegate, you can get it using this method :
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

Related

How to get/set the rootViewController?

Now,I gonna Develop an App ,which wants to switch from many different Views irregularly,also the views need to load large resources,AKA,it's hard to manage memory.Are there any good solustion?
PS:I created a ViewController as RootViewController,and When a button was Touch,run the code as
"ViewController=newController"
.The problem came,The new View loaded wrong way,it rotate so that couldn't show in a correct way.
I google for the solution,some one said ,I should replace the rootViewController,just like that,
[UIApplication sharedApplication].delegate.window.rootViewController=newController;
But I can't get/set the rootViewController in other class though it's a singleton.
Why not having a class that handles all the view switches ?
This article describes an architecture that might be helpfull: http://www.mikeziray.com/2010/01/27/handling-your-initial-view-controllers-for-iphone/comment-page-1/#comment-607

What's the purpose of the AppDelegate and ViewController files that Xcode generates?

I have written a few functioning iPhone applications, but mostly by following tutorials that tell you where to write the code. As a result I have gone without understanding what these files are actually designed to hold.
I made an app with code that is in the application method of the AppDeleagte file, so it gets called when the program runs. I wanted to make this code run on a button press instead, so I added a button, but when I came to put the code in the relevant IBAction, I realised all the variables and methods i needed were in the AppDelegate file, so I couldn't use them in the ViewController file.
So my immediate question is "how should I organise my code so that I can have it run on a button press?", but an explanation of the concepts behind it would be great too, becuase then I can do it without asking next time.
In short, the AppDelegate deals with application level events. Example: application becomes inactive, application starts etc. So whatever you need to setup when the application starts can go in there. As for your problem, I would suggest moving the variables to perhaps a singleton class or have another class that just contains variables and methods as a member in your appdelegate and do like madhu suggests. Having variables and methods directly in your app delegate works, but it can become big and nasty after a while.
import "AppDelegate"
in implementation file of viewcontroller
AppDelegate *app=(AppDelegate*)[[UIApplication sharedApplication]delegate];
[app inappDelegateDeclaredFunctionname];

access UISwitch setting from a different view?

k, I'm new to this so apologies all around, generally.
I'm trying to access the UISwitch value (on or off) from a different view and class and can't make it work.
It's a simple 2 view app. Main view and the second is a preference menu.
trying to write an if/else method to play sound when the switch (on the other view) is on and not when its off.
I cant seem to make it work. Any thoughts or some syntax examples would really help me out.
Thanks.
As Matt Wilding said "it's not good form to access UI components of one view controller from another...".
Instead of accessing the view object, when the switch state is changed by the user you save the status into NSUserDefaults as preference value. Whenever you want, you can access the switch status value through the preferences.
I'm going to take what I think you're trying to accomplish here and suggest an alternative approach. You want to have a preference in your app (assumed from "preferences menu") that allows the user to set something like whether or not you app plays background music. (May not be exact, this is just for clarification).
Typically, in a well designed app, the flow is driven by the data, with the UI reflecting the state of the data model and the controllers coordinating the two layers. What you are suggesting is to have your application play music based on the state of the UI, which is not backed by any data model. This cuts out the model level, and as you noticed, can lead to awkward attempts at communicating between the UI of different controllers for information.
Things like application preferences are typically stored in a nifty .plist file that is managed through the NSUserDefaults class. This would be a great place for the data level tracking of your preference. In this situation, the UISwitch would represent the state of the flag in the settings file, and changing the value of the switch would change the value in the file. Anywhere else in your application that you need to know if the play-sound-flag is set, you reference the data model info instead of the UI. This decouples the view controllers from each other, which is a good thing.
For this purpose add selector for swith and make NSInteger property in app delegate.Like the followed
[
yourSwitch addTarget:self action:#selector(switched:) forControlEvents:UIControlEventValueChanged];
-(IBAction) switched: (id)sender
{
int state=0;
if(yourSwitch.on)
state=1;
else
state=0;
objAppDelegate.switchState=state;
}
then you need to access this appDelegate property in second view where you are playing sound
then according to this value you can do what you want and for making object of appDelegate class you need this line
YourAppDelegateClass *objAppDelegate=(YourAppDelegateClass *)[[UIApplication sharedApplication] delegate];
ok if you have any other doubt then you can ask.

Passing Non-Static Objects Between View Controllers

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.

UITableViewController.view crash

So I'm trying to use a UITableViewController (let's call it homeView) in my iPhone application to display a simple table with only a few rows of text which are loaded from an NSArray in the controller. I want to display the table in the grouped style in a subview of a subview (let's call it subSubView) of my main controller. When I try the following: [subSubView addSubview:homeView.view], my app crashes on launch. However, when I allocate the object without adding it to any views, it launches fine.
What's the best way (or rather a working way) to display the table generated by my UITableViewController?
There isn't enough to tell for sure what is going on, but if I had to guess I would think that you probably aren't retaining homeView. Normally I would say that as a comment to your question, since it is not really an answer, but I have a completely separate answer:
Just use a UITableView, not a UITableViewController. Instead of trying to embed a controller within a controller (which is quite difficult since Apple doesn't expose the necessary tools to actually modify the view controller hierarchy), just make the VC you are writing support the appropriate delegate/dataSource methods and directly create the view.
While it might make some logical sense to try to embed VCs inside of each other, with the exception of the builtin container VCs (UINavigationController, UITabBarController) it Really Doesn't Work™. The technical reason for this is that internally some of the event routing and messaging depends on parentViewController being correct, but since you can't set it (setParentViewController: is private) tons of latent bugs in UIKit start rearing their head. The internal collection classes can set the parentViewController correctly, so everything works right.
Also, one last thing. In your question you named your view controller homeView. Please, please on't do that. A view controller and a view are separate things, call it homeViewController. Aside from the fact that a lot of new iPhone developers get confused about what the distinction is, there is nothing more aggravating then tracing through someone else's code and realizing that something you are assuming is one type is another.