How to Use Constant String Variables in Interface Builder - objective-c

I created Constants.h and Constants.m as suggested here:
Constants in Objective-C
Now I want to also use some strings defined in Constants.h in Interface Builder to for example set the text of a label.
How to do this using bindings? I think I should somehow use an ObjectController (Mode: Class, Class Name: Constants)? But what would be the Content Object for this controller (since I don't have any variable of type Constants)? Maybe use a Singleton in Constants.m? Any suggestions?

I don't think you can bind the strings in any way.
I would recommend do it in code in viewDidLoad.
Note that string constants aren't so great for texts in UI.
EDIT:
Xibs have their own localization system but I don't think it's very good. It basically means creating a new xib for every language. If you support only one language, just put your strings into the xib and the problem is solved.
NOTE: the following is an idea for my current project and I haven't implemented it yet but I suppose it would let us easily add new language translations.
My idea for a better xib localization is to define IBOutlet for every localizable component (e.g. myButton1, myTextField1) and then write a file with localized strings (xml, properties, plist whatever) where every string is keyed by the IBOutlet name, e.g:
myXib1.myButton1.selected.title = This is a button.
myXib1.myTextField1.placeholder = "This is text field placeholder"
Then, you have to write a method which takes the xib name, finds current language and goes through all string properties for the given xib. It can use [NSObject performSelector:] to access the IBOutlet getters:
id localizableView = [self performSelector:NSSelectorFromString(#"myButton1")];
and you call this method from viewDidLoad (or you create a UILocalizedController class which calls it automatically and all your controllers will be its descendant).
Also note there is NSLocalizedString class which should help you with localization.

Related

Curiosities noticed while learning Objective-C and Xcode in general

While specifying an instance variable that provides a connection between the view controller and the View, we use the IBOutlet keyword prior to the View object type. This helps indicate that it is an instance variable connecting to the View.
However, is there a scenario where I would not require the IBOutlet keyword preceding my view Object type? For example: can we have a scenario where a:
UIButton *display ;
has some kind of use vs
IBOutlet UIButton *display ;
This question stemmed out of curiosity.
Another question that I have probably has to do with understanding the nuances of interfaces and C in general.
In the view controller or any controller as such, we tend to "import" the header files and not the implementation files. I am at odds with this concept and again it is just a curiosity?
The "IBOutlet" keyword doesn't change anything about your program, it just allows Interface Builder to recognize what connections are available. If you don't need to connect something in your interface (for example, if you just want an instance variable for private storage, or if you want to use an #property), then you don't have to use IBOutlet.
We import header files just so the compiler knows what classes and methods are available when using them from other places in the program. An implementation file doesn't need to be imported; it only needs to be compiled into the program and the things it contains will be available.
To the compiler, IBOUTLET is a null operator. It means nothing. It's only purpose is to tell Interface Builder that you intend to connect it to an interface object.
Header files define the interface, and that's all the other class implementations need.
Joe
IBOutlet and IBAction helped Interface Builder detect what outlet and actions you wish to connect to your UI controls, at compile time these IBOutlet and IBAction are ignored and have no use.
I believe you don't need these keywords anymore in Xcode 4.0+.
You can have a scenario where you don't need IBOutlet or IBAction, when you are building UI controls programmatically (in code).

Dynamically List IBOutlets of a Class

I've been working with this
objc_property_t *properties = class_copyPropertyList([NSString class], &outCount);
which has two limitations that I don't know how to resolve:
It doesn't list inherited properties.
I can't differentiate IBOutlets from other properties.
How can I dynamically list all the IBOutlet properties in a class (or instance)?
IBOutlet is #defined as a blank string; it doesn't have any effect at either compile or run time. Its sole purpose is to allow Interface Builder to look at header files and see which ivars should be used as connections. The only way for you to determine which ivars were declared as IBOutlets would be to likewise do some text processing of the header file of whatever class you're working with.
For the properties, I'm not sure there's any other way than going up the list of superclasses and getting all their properties too. You can call class_getSuperclass in a loop to get the whole ancestry of your class;* the function returns Nil when you call it with the root class (NSObject) as the argument.
*See, e.g., this SO answer of mine.
from what I've read this is not possible. The reason is that IBOutlet is a macro that resolves to nothing. So there is nothing in the compiled app to detect. It is used by interface builder which looks at the raw source code where it can see it.

split iphone objective-c code in to multiple files

I have written a few apps for the iphone now, but they are all written in what I consider to be a lazy, unstructured way.
I have started a new project and have created several Objective-C classes (subclass of NSObject). the problem I have is getting the logic correct in my head. My structure is as follows
viewController.h
viewController.m
plotPoints.h
plotPoints.m
handleFeeds.h
handleFeeds.m
So the main file is the view controller and I include in it's header file the other classes. My problem is that in the other class files, eg plotPoints.m - if I try to refer to a variable I set in the view controller, it says it's not set. I have included the viewcontroller in the plotPoints.h file - but still it doesnt work.
what is best practice for separating code in this way? In this example, I have webservice feeds which I want to handle in one class, then process those results in another and handle the main UI in the view controller.
Thanks for any information.
I say the Controller shouldn't be referenced by your - as I understand - external classes (plotPoints and handleFeeds, by the way these should definitely begin with an uppercase character).
Actually, it should be the exact opposite, your viewController should be using methods and properties of your external classes. PlotPointsand HandleFeeds should not have to refer to instance variables of your Controller, let it pass them as arguments for you methods instead.

iPhone SDK basics, one view available from several classes

I'm curious if it's possible to create an application according to window-based pattern, add UILabel, create a new class, and to be able to change UILabel's value from this new class.
After creating all that files we will have:
NewApplicationDelegate.h, .m;
Newclass.h, .m;
MainWindow.xib.
The IBOutlet in this case must be added to MainWindow.xib, and I want to change its value from NewCalss.m. Is it possible? How can I do that?
The point is that I was working only with navigation-based or simple window-based applications before, and now I need to have one view available and changeable (UILabels, for example) from at least 2 other classes.
Thanks.
You will have a UIController object too - right?
That has a handle on the UI elements, UILabel etc, whichever you map through.
You could pass this to the Newclass or you could provide an interface/protocol that the controller exposes that allows Newclass to interact with what you want to do.

Passing a value from one object into another with Objective-C

I have a class called GameScene, with is a subclass of a cocos2d Scene.
In there I have two layers. GameLayer and ControlsLayer. You can probably tell already that I want the ControlsLayer to move stuff around in the GameLayer. To be precise, I'm trying to control a cPBody in the GameLayer from the ControlsLayer.
At the moment, I'm trying to route the instructions from the ControlsLayer, back up into the GameScene and then back down into the GameLayer. If that makes sense. Anyway, I can't get it to work. I have a PHP background so I think I'm incorrectly applying my PHP experience to Obj-C.
My thinking is, I should be able to access a property inside a class/object using something like
aThing *someThing = someInstance->aThing;
From the sample code I've been looking at, it looks like this should work. But it doesn't. Here's the code, stripped down to as much as possible http://pastebin.com/d49c9d0be
Rather than knowing how to fix this particular issue, The question is, what don't I understand?
In Objective-C you need to define accessor methods to get at the instance variable, you can't directly access it like that unless you're calling it from the same class type (for instance when you're implementing the NSCopying protocol and need to set private variables, but don't worry about that now).
The easiest way to do that is to define a property in your header using #property(retain) SomeClass *name;, and have Objective-C generate it by putting #synthesize name = instanceVariable; in your implementation. You can then access the variable outside of that class using object.name; or [object name];. For more information take a look in the documentation for properties and Object Oriented programming.
You're not exposing the gameLayer.myBody property in any shape. You'd have to use the #property declaration (assuming objective-c 2.0) (here's an example).
I don't have any PHP background, so I don't know how it may be different in PHP.
The correct way to access a property in an object is as follows:
aThing * someThing = someInstance.aThing; // new style
or
aThing * someThing = [someInstance aThing]; // old style
If you were coding in c, the -> operator would make sense. In objective-c, however, objects are always passed around through pointers. No objective-c variable ever actually holds an object, they just hold pointers to objects. The language designers simply decided to use the [] or . syntax to access members, so that's what we have to do!