There's some way to declare Strings and Variables in Obj-C for iPhone?
I mean, i want to display the data input on textfield in 01.xib on 02.xib label's.
How can i do that?
Thanks!
You'll need a class that communicates between the two, getting the relevant value from the textfield in your first XIB and setting it as the value of the label in your second. This is quite a basic sort of operation, so I guess that hints and keywords are the best way forward.
Your first XIB will have a class nominated as 'File's Owner'. That should match a class in your Xcode project. Things defined in Interface Builder access one another through outlets. So you at least need an outlet from the owner to the text field. You may also want it to be the text field's delegate, depending on what means you're using to decide to move from the one NIB to the other.
Much of the time, iPhone people set the File Owner of a NIB or XIB (the terms are interchangeable) to be a subclass of UIViewController. So probably you'll have an outlet to both the text field and the view controller that owns the second XIB. General program flow will be that, upon the relevant event, it reads the value of the text field, communicates it to the other XIB and then presents the other XIB.
Similarly, the second XIB's owner (another UIViewController, probably) will have an outlet to the label and will use that to set the value.
Interface Builder is for drawing out the interface and connecting objects to define who knows about who. Xcode is for writing actual code. If you stick to model-view-controller then Interface Builder helps you draw the view, then you code up the controller and model for yourself. UIViewController subclasses are, as the name suggests, meant to be in the controller layer. Objective-C is another language derived from C (which, unlike C++ or C# is a strict superset) with many of the same ideas about semantics.
It's difficult to elaborate on any of that without elaborating on all of it and writing about 20 pages.
Two view controllers are the owner of the two xib file. They should have property declaration for UITextField and UILabel.
(02.xib'x label).text = (01.xib's textfield).text;
Related
I would like to use a single WizardViewController with different inputView subviews. The WizardViewController would share a searchCriteria and pass it along to each new step, with each step adding to the criteria depending on the input for that particular inputView.
The problem I am facing is how to structure my objects/views so that I can reuse WizardViewController accepting different types of input/controls. For example, I've thought of using a WizardViewModel that had members like enum wizardViewModelType (for each type of view), UIView *inputView that corresponds to each type of WizardViewModelType, and creating custom UIView subclasses that correspond to the different possible inputViews that would be needed, connecting outlets as necessary in Interface Builder. The problem is that I believe that going down this road will lead to a lot of inter-class dependencies and basically defeat the purpose of separating the inputView logic from the WizardViewController. Furthermore some of the inputView will require me to grab possible values from a web service, which is something that the ViewModel will have to handle, further breaking the logic. Perhaps I need separate ViewController for each type of input view? Or am I thinking about this in entirely the wrong way?
Normally, the right way to do it is by having a ViewController for each UIView. The logic of your application should not be on the view, but on the viewController, and you can share data by using segues (if on ios 5), and I'm sure that there are other methods for ios 4 or below.
If I wanted to share codes between the UIViewControllers, the way I would do to make a wizard is to embedded it in a navigation controller and push the next viewController on the navigation controller stack.
If you want to share code between view controllers, I don't think you should do it on the view controller class. Basically, I would think of two options to do that:
1) write a base class: the base class should extend the UIViewController and your UIViewControllers could extend this base class.
2) extract the common code into another class (better, if applicable): You create another class that share the common code, and inject it into your view controllers.
I am new to mac dev, xcode and IB etc. I understand how to build simple applications and basic dragging & dropping in IB, but i don't know what and where does IB do with the objects.
the second questions is how to write a MVC without using IB?
When you connect two objects in IB with IBOutlet or IBAction it creates some special tags in XIB (which is XML).
When bundle (update: sorry, it's not a bundle, but UINib) reads NIB (which is compiled XIB) it looks for such tags and objects they are refer. After that:
For outlets it uses KVC (Key-Value Coding) to set corresponding property of receiving object.
For actions it calls addTarget:action:forControlEvents: on control object.
You can build iPhone app of any complexity without IB by creating and setting up objects in your code, but in most cases it's just not wise.
Further reading - Resource Programming Guide
As far as I know, the XIB files from IB are some kind of archives with your objects and their properties stored in them. When you send -initWithNibName, the objects are unarchived. So basically, you could - if you knew how - create your own XIB files and they should work. Note that loading a UIViewController without specifying a XIB file, an XIB file with the same name as your class is loaded. See the Wikipedia article.
To your second question: You can create any object you add using IB programmatically. Typically, these are UIView subclasses that you initialize using initWithFrame:. Then you set the properties you need. Finally, you add them to your view using addSubview.
IBActions are basically Target/Action Pairs. If you for instance add UIBarButtonItem, you use initWithBarButtonSystemItem:target:action:. Setting the action is equal to setting an IBAction connection in IB.
You should be able to create any User Interface you want programmatically, however it's usually a lot of work compared to when using IB.
Being new to Xcode and Objective-C I find it hard to get my head around the Interface builder and Objective-C when doing things that are following the basic pattern. I have created a subclass of UIViewController that I want to instantiate several times to make a grid with each row being controlled by an instance of this class. So there will be one root view controller (with navigation etc) that should include/genereate all the instances of the custom sub-viewcontroller.
Now what would be the best way to do this? All examples I can find are about navigation, where one view should replace another, but I want to have all the viewcontrollers visible on the same "page". Do I need to create a nib file for the custom controller at all? I have also been thinking about using the UITableView somehow but inserting my custom viewcontroller in every row.
Any help greatly appreciated!
Apple's documentation recommends using one view controller per screen. It is possible to decompose your interface and use multiple view controllers on one screen if you have a good reason to do it, but Apple hasn't really designed their frameworks to support this, so you'll run into pitfalls if you don't know what you're doing.
In this case, I question whether each row of your grid really needs its own view controller. I find it hard to imagine a case where this would be the best choice, although it's hard to say for sure without knowing more about your app. Some things to consider:
What is your custom controller doing? Is it mostly changing the visual appearance of its corresponding grid row? If so, perhaps it would be more appropriate to subclass the UIView itself.
If this object is really behaving as a controller and not a view, consider implementing it as a subclass of NSObject rather than subclassing UIViewController. The UIViewController for your screen can capture events and delegate them to the appropriate custom controller object, or your custom views can capture their own events and notify their associated controllers of those events directly using a delegate pattern.
If you're sure you have a valid reason to implement these objects as UIViewController subclasses, check out my answer to this question.
This should be a pretty easy fix, but I haven't figured out from reading the Apple documentation or other SO questions how to do this simple switch from creating my Interface programmatically to using Interface Builder.
I am basing my code around this framework:
http://www.pushplay.net/blog_detail.php?id=27
The only difference is that, where each View is programmatically created (View01.m, View02.m) in ViewDidLoad, I instead want to import from a nib (while still using this framework) for each view (each view has a unique IB design).
Thanks for the help.
Think of IB as an Object Creator and not a code generator. That really helps. What IB does is actually create instances of objects as they are dragged on to the desktop/view/XIB window. It then allows you to start creating various connections (with a control drag on the mouse) from one object to another object. You then instantiate the entire XIB by unarchiving it from your bundle. This is highly automatic and reading up on UIViewController should move you along a bit. Look at:
initWithNibName:bundle:
You basically have two types of connections:
Outlet: This is how you teach one object about the existence of another object. For example, you might have a controller object that needs access to a button. You create an outlet (either in XCode Text Edit in the controller.h file/property area or in IB by adding an outlet) in your controller and then control-click-drag from the outlet to the button.
Actions: This is how you trigger an event on one object to call a method on another object. Actions will have a prototype of:
- (IBAction) someMethod:(id) sender;
I think the ":(id) sender" is optional if your method does not need a link to the object causing the event.
Within IB, you can arrange objects and set various attributes like size, color, position, target/actions, user interactions, Files Owner...
That brings me to files owner. Big concept here. It tends to be the Controller that loads the NIB (OK: I have a custom window controller I have used for over 15 years but Apple has a really good one UIViewController that does all sorts of goodness.) and acts as a proxy in IB. It is not actually instantiated in IB but it will be when you alloc and request it to load the NIB (XIB files are XML files that are turned into NIB files by the compile process)
As I move more and more of my UI construction from XCode to IB there is one remaining hurdle I need to clear.
Currently, I create my custom viewControllers in XCode with custom initializers. They typically have a bunch of ivars that are set during initialization via passed params. I would really like to move as much of this as I can to IB.
Could someone carefully explain to me - or, better, point me to code - how to replicate the XCode approach of passing params via custom initializer in IB - presumably via IBOutlet.
Thanks in advance.
Cheers,
Doug
UPDATE:
A typical scenerio is my AppDelegate will go out to the network, grab some data - NSMutableData, and then pass a reference to a root viewController - typically a TableViewController - that is pushed on the viewController stack of an navigationController.
When a cell is selected an secondViewController is alloc/init'ed and a subset of the data is passed to it. The secondViewController goes to the network for a bit more data, builds a view hierarchy, hands bits of the retrieved data to each subview and then each subview is messaged with setNeedsDisplay to process the data.
It is this hierarchical data passing that I want to hand off to IB is possible.
You can still have a custom initializer. However, inside this initialized you'll call -[initWithNibName:#"yourNibName" bundle:bundle]. You will connect your UIKit related instance variables (UILabel, UIButton, etc.) in Interface builder and therefore won't have to instantiate those objects in your initializer. Other instance variables (strings, dictionaries, custom objects, etc.) you'll instantiate and set in your initializer.
Also, keep in mind that manipulation of your UIKit related variables such as setting label text, or setting the position of a UIView, should be done in the viewDidLoad method since these objects may not have been fully created at the time initializer is executing.
Let me know if you need more information.
Lets say we have MyViewController which extends UIViewController and MyViewControllerParameter which is one of our custom objects we pass into MyViewController on initialization. MyViewController has an IBOutlets of type MyViewControllerParameter defined in it. We want to put MyViewController into another containing view, ParentView.xib. ParentView.xib is owned by ParentViewController.m and created elsewhere. We double click ParentView.xib in XCode to launch Interface Builder. We then drag an "object" from the Library View (I believe you open the library view with Cmd+Shift+L if its not open by default) onto the Document window. (This is the window activated by Cmd+0.)
An "Object" is an arbitrary widget found in the library (identified by a solid gold cube icon) that can represent anything in your project. After we've placed the new object into the document window, we type Cmd+4 to open the Indentity Inspector Window. In the top text field we can type the name of our view controller parameter, "MyViewControllerParameter". Next we find the ViewController widget in the library and drop it into the document window. We open the Attribute inspector (Cmd+1) and set the nib name to "MyView.xib". This should cause CocoaTouch to load MyViewController using the definitions in "MyView.xib".
Open the identity inspector and set the class attribute to MyViewController. Last we right click or control click (or two finger tap if we've correctly configured the trackpad on our MacbookPro) MyViewController in the document window. That will open a window showing all of the IBOutlets in MyViewController. Drag a line from the little open circle next to the MyViewControllerParameter outlet and drop it on the MyViewControllerParameter object sitting in the document window. Connecting these dots is how you set parameters between objects using interface builder.