I have a app that uses several view controllers. In one instance I need to uses an int (int lives) in a seperate view controller from where it is created. I have tried using it and it throws and error at build claiming "lives" undeclared. I am already importing the view controller where the int was declared. I am stuck on this one.
I would appreciate any help.
Use properties, or custom setter and getter for instanse variables.
You could use the application delegate to store information you need in different places in you app.
The proper way would be to implement your own delegate protocol. For a recent discussion on this topic, see pass a variable up the navigation stack
Related
I have multiple interface controllers that are both open at the same time in a paged-based format. I need to share information between these interface controllers.
For my use case, I cannot force the user to one of the other interface controllers (by initiating a segue), so the those solutions will not work for me. I need to be able to change some variables in either controller, and access those variables in either controller.
I tried directly setting a variable in an interface controller that is not currently visible in this way:
InterfaceController2().variable = false
But, this didn't work (as expected) since this is not accessing the currently instantiated instance of that interface controller.
I am considering some sort of global variable situation, or storing preferences in UserDefaults, but I feel like there must be a better way.
You could use a singleton. The easiest way to create a singleton is to make the variable you want to share between InterfaceControllers a class/static property.
You can create it like this:
class CommonClass {
static var mySingleton = true
}
Then access it from your InterfaceControllers like this:
CommonClass.mySingleton = false.
You should be cautious when using singletons, since they can be accessed anywhere from your code, so they can be misused to act like global variables, which can have its pitfalls.
Check out this article for more details about singletons.
Best option: If your controllers have a common parent, you could use delegate methods to pass/retrieve values from the common parent.
Alt: You could create a shared instance that stores your values and your controllers can update/retrieve the value from there.
Final option: It's a little gross, but you could use NSNotificationCenter. (a) add observers in all of your controllers, (b) post notifications whenever a value updates. And then (c) update the local values in your controllers within the notification handlers.
I have a general working knowledge of object-oriented programming and I'm currently trying to create an interactive novel program in Objective C using Xcode 4.2 with storyboarding.
I have a storyController class that instantiates the page objects and a viewController class that needs to display the pages. My fundamental question is the best approach for my storyController to tell the viewController to update it's text to display that of the new page object. My instinct tells me that my storyController needs to call a method on the viewController and pass it a page object. However, I'm not sure how to reference the view controller since it seems to be automatically created and linked by the storyboard (I don't see the viewController instantiated in the appDelegate).
I've read this post: http://www.iphonedevsdk.com/forum/iphone-sdk-development/54859-sharing-data-between-view-controllers-other-objects.html and it seems to address the issue. I could make a shared object on my appDelegate and use KVN or NSNotification to tell the view controller to check it.
I've also been reading about delegates and protocols as possible solutions.
So considering these potentially different approaches, which would be best to tell my viewController to update itself and pass it an object that contains the updates?
I would suggest looking at the UIPageViewController class, which probably will do a lot of the heavy lifting work for you, depending on the specifics of your app. This class is essentially a controller class that contains multiple viewControllers. Each managed viewController becomes essentially a "page" in your book.
Here is a tutorial using UIPageViewController.
If this approach won't work for your app, I'd still suggest using a separate viewController instance for each "page" of your book and handle the transition between the pages with segues.
I have setup and successfully logged in via xAuth using an extended class of MGTwitterEngine, my question is if I want to pass this to another view controller, how can I change the delegate class, as it is some sort of weak reference
#interface MGTwitterEngine : NSObject <MGTwitterParserDelegate> {
__weak NSObject <MGTwitterEngineDelegate> *_delegate;
Am I best wrap this up into a singleton class and pass around that way, seems overkill to login in each time, or have I missed a painstakingly obvious way of sharing this object around
At the moment I have added a setDelegate method to the MGTwitterEngine but feel as though I am fighting the framework unnecessarily
If you're sharing the engine across multiple objects then you would want to have some other object/singleton wrap the engine and act as its sole delegate. If you've done database programming then think of it like a database connection -- you probably wouldn't have each view controller create its own database connection. Instead you'd create some sort of data manager object that is shared by the views and possibly abstracts away some of the DB internals.
If different view controllers handle different tasks -- like login, looking up users, querying messages, etc. then the delegate methods in your wrapper should be able to pass the responses along to the appropriate view controller.
If you have different view controllers calling the same methods (and if so, why?), you could still route responses back to the corresponding view controllers. As the MGTwitterEngine docs say, "Each Twitter API method returns an NSString which is a unique identifier for that connection." You would just need to pass an object (your view controller) or a block as an extra parameter to each of your wrapped methods. You can cache the twitter id string and this object/block in a mutable dictionary when your wrapper sends the response, then look up the connection id in the cache when it's time to handle the response.
actually, you can.
The delegate, is nothing but a variable in the MGTwitterEngine. Just add a instance of it in the next view controller adding the proper header and inplementation calls.
after instatiating the new view controller set:
nextViewController._mgTwitterEngine = self.mgTwitterEngine;
nextViewController.mgTwitterEngine.delegate=nextViewController;
then call the nextViewController.
Do not forget to set the delegate back to the original view controller when you return to it (either on viewDidAppear or viewWillAppear)
Hope that helps...
Best Of luck!
Use NSNotifications in the delegate.
Make the view controller where you wish the delegate to be add an observer. Have the delegate method for MGTwitterEngine post the notification.
I am developing a special type of view controller for an iPhone component library.
I have got the who view controller working well, but I need to change it so that it works in one of two ways:
Either it is an abstract class which you must subclass and provider the implementation for a specific method which the controller will call whenever it needs its data.
Or it needs to be a useable class which has a property which is a selector... when you set the selector it specifies the method which should be called to collect the data.
I would like to know how I can implement either of these and which you would recommend
The standard way of doing this in Objective-C and the iPhone is through delegation.
Normally you provide a property in your view controller called delegate that is typed for a particular protocol you create. Then who ever is using your view controller will set the delegate property with their delegate for your view controller. You can then call the methods in your protocol on their delegate.
See the answer at this SO question for a full example.
Also read the Cocoa Fundamentals Guide for information on what delegates are and why they are used in Cocoa. There is also an example there of how to create delegates for your own custom classes.
My tabBarController-based app has several tabs. Each has a custom viewController class, the only difference being the way the instance is initialized. Is there a way to make interface builder send the different tabs custom init parameters?
Currently I'm doing the initialisation in viewWillAppear, but for a bunch of reasons it would make sense to do it in IB instead of in the code.
Any suggestions?
thanks,
Kelso
Interface Builder creates an archive of objects that is unarchived when you program executes. You can't really tell IB to call particular methods.
If you need to initialize before viewWillAppear: is called, you can do so in awakeFromNib, which is guaranteed to be called after all objects have been loaded and all outlets have been connected to their targets.
If you want to do initialization even earlier, you can do so by overriding initWithCoder: (see the NSCoding protocol for documentation). I don't know if it is documented anywhere, but that is the designated initialized for objects being decoded from an archive.
In all of the above, you won't be able to receive parameters, but in the code you should be able to access whatever you need with some judicious use of global variables. You can also use [[UIApplication sharedApplication] delegate] to get access to your application delegate object.
I don't think there's any way to change what methods are called by the IB runtime when your nib is loaded. If you described what you were trying to accomplish (i.e. why doing the setup in viewDidAppear doesn't work for you), you might get a suggestion of a better way to handle your initialization.