When I add new view, I always do same and boring work.
If I add UIWebView, I would do follows,
add codes to header file. ( declare, property )
add codes to source file. ( synthesize, viewDidUnload, dealloc )
add UIWebView in IB and connect to the outlet in File's Owner.
[ViewController.h]
#interface ViewController : UIViewController
{
UIWebView *_webView;
}
#property (nonatomic, retain) IBOutlet UIWebView *webView;
#end
[ViewController.m]
#synthesize webView = _webView;
- (void)viewDidUnload
{
[super viewDidUnload];
self.webView = nil;
}
- (void)dealloc
{
[_webView release];
[super dealloc];
}
What if I should add 3 labels and 2 buttons?
What if I have to add textview and some imageviews?
Don't you think it is boring? I would like to listen to your idea.
I hope there will be more easy and simple way to add outlet to the code.
Does anybody have a good idea? :)
When using Interface Builder, If you select an Object drag it's reference to your header, you'll see a popup where you can name it so theres less typing for you to do. As seen below:
This will automatically declare the IBOutlet UIButton *myButton for you, and insert the release and nil code into dealloc and viewDidUnload methods.
Same method also works for actions, as seen below.
Once you Connect it will automatically insert the new Action -(IBAction)cancelSelected:(id)sender into your #implementation class.
Point being, all that's boring for you to do can be done in 2 Reference connections, and inputting data into 2 fields. :)
Hope this helps!
In Xcode 4, you can simply control drag from a UI element to the .h/.m file. If you drag to the .h, Xcode will create a property for you and synthesize that in the corresponding .m, if you drag to the .m, Xcode will stub out an IBAction method for you.
Also, I would recommend switching to ARC, to avoid having to worry about memory management.
If you are having xcode 4.0 you can create outlet property by drag and drop.
Follow the steps:
open the xcode
open you nib file where you need to create an outlet.
Click on the middle tab of the Editor which at right up corner. It will open a new file adjacent to your nib.
Make sure it is the .h file of the controller where you want to create the outlet.
Now select the control, right click on it and drag to the .h file. Name the outlet. Thats it. It will create you a property and it will synthesize it automatically.
It will also insert the code for dealloc and viewDidUnload.
Hope this help.
Related
I am trying to use storyboards in my application. I began well, I have added two view controllers with a button to go from the first to the second.
The problem is in this second view controller: the objects I add on it and link with the code do not work. When I set a breakpoint in the view controller code, the 'self.property' is set to nil, whereas it should be instantiated by the storyboard.
I have been looking for an answer for hours, and I really don't understand the problem, since all the rest seems to be good.
I have tried to write the property in the code (strong/nonatomic, nonatomic/retain and even weak/nonatomic), to link the object directly to the code so that it creates the property automatically, but I never get anything else than "nil" with breakpoints.
viewController.h:
#interface NMLoadingViewController : UIViewController
{
__weak IBOutlet UIProgressView *imageProcessingProgressView;
}
#property (weak, nonatomic) IBOutlet UIProgressView *imageProcessingProgressView;
#end
.m:
#synthesize imageProcessingProgressView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Custom initialization
NSLog(#"INIT.");
}
(amont other lines of irrelevant code)
If I set the breakpoint to the "INIT." line, my imageProcessingProgressView is nil. I can't see a reason for that, I guess I have missed a very little detail...
(Note that I have tried this with other objects, like a UILabel, but it did not work either. Stranger, when I had two objects, one of them had an adress which was not nil, but still it was corrupted and did not show the right object.)
Edit: It was a lot of trouble for nothing... The problem is about the Variable View in XCode, which show my variable to "nil", whereas a log shows me a correct object...
Remove this...
{
__weak IBOutlet UIProgressView *imageProcessingProgressView;
}
...and make the property strong.
Change your log message to...
NSLog(#"INIT: %#", self.imageProcessingProgressView);
...and see if you still have a problem. If you do, then take another look at your storyboard connections.
Make sure NMLoadingViewController is the class on your viewController
First try out the answer by #Eric because I do believe that is the real issue.
Also, make sure that you are actually using the interface builder to hook the controls back to the view controller. This is done by dragging a line from the control back to the property of the view controller.
I have the following problem. I've created a ViewController pretty much like the above
#interface MyViewController : UIViewController {
IBOutlet UITableView *myTableView;
}
#property (nonatomic, retain) IBOutlet UITableView *myTableView;
I've linked myTableView on the Interface Builder to the matching nib's UITableView. and I've subclassed MyViewController to create YourViewController as so:
#interface YourViewController : MyViewController {
}
And then I load from a TabBarController the YourViewController on a tab item. Although I can see that MyViewController is indeed invoked at the end, no table view is displayed on the emulator.
I've tried debugging the MyViewController and it appears the the IBOutlet is nil.
Why is that?
I have encountered major issues with inheritance and IBOutlets and IBAction. I advise you to avoid that, and create shared stuff in another way.
I was hit hard by bugs when getting memory warnings for instance. Outlets and actions didn't get reconnected properly when they were defined in base class vs derived class.
Probably MyViewController's nib file is not loaded at all. Are you using for YourViewController a specific nib file? and in which way are you creating YourViewController.
Can you also try to define an "awakeFromNib" method in YourViewController and then from it call [super awakeFromNib] ?
However to understand your issue you must clearly explain how you load objects and if and where you use Nibs?
If you add it dynamically using code then only it will work. Not using Nib.
the UITableView (ie. your myTableView) needs delegates for data source and and its control.
And your controller needs a link to the Table view in the xib.
declare table delegate protocols in the interface section of your controller.
using IB, link the TableView in your xib to owners file:delegates.
using IB, link the file owner myTableView to the tableView in the xib.
I hope it will help.
Assuming that you have your whole navigation stack in MainWindow.xib
Open MainWindow.xib
Select YourViewController (Or whatever your controller that is subclassing UITableViewController is called)
Select Attributes Inspector
Ensure that the 'NIB Name' property has your correct YourViewController (Or whatever the name) selected
I had this exact same issue, this solved it for me.
My problem is that I cannot access any of the controls in a view defined using interface builder. This is the .h code for the Navigation bar (as an example):
#import <UIKit/UIKit.h>
#interface myController : UIViewController {
IBOutlet UINavigationBar *tTitle;
}
#property (nonatomic,retain) UINavigationBar *tTitle;
#end
The implementation (.m) is:
#import "myController.h"
#implementation myController
#synthesize tTitle;
- (void)dealloc {
[tTitle release];
[super dealloc];
}
- (void)viewDidLoad {
tTitle.topItem.title=#"This is my title";
}
In viewDidLoad tTitle (and my other outlets) are always 0x0. I have omitted the two text fields and the button for brevity.
This exact code works in another view in the app without issue. In IB I right click on the file owner icon and it shows my outlets correctly (and the single button action). Yet at run time - nada. I click the button and no response. The title is still the default title. I cannot set the text fields text property because the fields are all 0x0.
The view is linked to the view controller. As near as I can tell everything is identical between the two views that are doing the same thing. Obviously something is awry, but I can't figure it out. Any help would be appreciated.
Okay. I did the ROI and figured it would be easier to delete and recreate the view (one control at a time) in an attempt to see where it was going awry. The answer is the title bar title set worked from the get-go. I have no idea why the other class didn't work. But discretion is the better part of valor in this situation. The new class is working fine. Thanks for everyone's input.
I'm a beginner to Iphone Development :)
I am trying to make a button change an image. So I have my button
- (IBAction)myButton {
myUIImageView.image = [UIImage imageNamed:#"myPhoto.png"];
}
I created a UIImageView in IB and I named the label and the name of this 'myUIImageView' but XCode is telling me that it's undeclared. So my question is how do I associate this UIImageView with myUIImageView. Or perhaps how do I reference this UIImage in my myButton IBAction?
Any advice would help, thanks alot!
In your .h, you need this ivar between the curly braces
UIImageView* myUIImageView;
And after the close and before the #end, you need
#property(retain, nonatomic) IBOutlet UIImageView* myUIImageView;
and in the .m, after the #implementation line
#synthesize myUIImageView;
(release in your dealloc and viewDidUnload)
Now,
Open up Interface Builder for the .xib for this view controller
Click on File's Owner icon in the Document dialog
Bring up the Inspector
Go to the connections tab
You should see an outlet named myUIImageView with a circle next to it
Click and drag the circle to the UIImageView in your view (this connects the outlet to the view)
Save, close, rebuild
how to connect the UIImageView in interface builder with the outlet created in xcode named myUIImageView:
close interface builder and open up xcode. Heres what you need to write correctly in the following two files.
in XCode
.h file
#interface FirstViewController : UIViewController {
IBOutlet UIImageView *myUIImageView;
}
#property(retain, nonatomic) IBOutlet UIImageView *myUIImageView;
#end
.m file
after implementation you write
#synthesize myUIImageView;
release in your dealloc and viewDidUnload.
save the file in xcode then open up the xib file that is connected to the .h and .m files. For example i have firstViewcontroller.h and firstViewController.m then i have a .xib file called firstView.xib.
in Interface Builder
Now on the view drag a UIImageView and then in the document dialog you will see the file owners icon.
click on that and press CMD+2 to open up the inspector. Go to the connections tab and there will be an outlet named myUIImageView that we created in xcode. next to it is a circle which you click and drag to your UIImageView. This will connect the outlet in xcode with the imageview in interface builder.
Now save the file. close interface builder and rebuild your project.
Thats the first question answered once you ellaborated on question two i will help you with that.
Let me know if you need any more help.
PK
I am new to the iPhone SDK and am trying to create 3 views and switch between them. Data will come from a server and I will basically be showing 1 view and caching the other two. So far I am just trying to create a view and display it at run-time. My code is listed below. It shows only a blank screen and I think I am missing a key concept. Any Help?
#import <UIKit/UIKit.h>
#import "ImageViewController.h"
#interface Test5ViewController : UIViewController
{
IBOutlet UIView *rootView;
ImageViewController *curImage;
ImageViewController *nextImage;
ImageViewController *prevImage;
}
#property(nonatomic,retain) IBOutlet UIView *rootView;
#property(nonatomic,retain) ImageViewController *curImage;
#property(nonatomic,retain) ImageViewController *nextImage;
#property(nonatomic,retain) ImageViewController *prevImage;
#end
and
- (void)loadView
{
self.curImage = [[ImageViewController alloc]initWithNibName:#"ImageView" bundle:[NSBundle mainBundle]];
UIImage *pic = [UIImage imageNamed:#"baby-gorilla.jpg"];
[self.curImage assignImage:pic];
self.rootView = self.curImage.view;
}
and
#import <UIKit/UIKit.h>
#interface ImageViewController : UIViewController
{
IBOutlet UIImageView *image;
}
-(void)assignImage:(UIImage *)screenShotToSet;
#property(nonatomic,retain) IBOutlet UIImageView *image;
#end
Welcome to the iPhone SDK!
In general, there are two ways to get any view displayed.
First, and most commonly, you use a NIB file created by the Interface Builder. This is usually the easiest way to get started and I would recommend it for what you're trying to do here. It's too lengthy to describe all the steps you need to do for what you have here, but basically start in xcode by creating a new file and selecting "user interfaces" and choose View XIB. This will create a basic NIB file (they're called NIBs rather than XIBs for historical reasons). The first step in interface builder is to change the class name of the "File's Owner" to your UIViewController subclass (Test5ViewController). You can then drop anything that IB will allow into the view window or even replace the pre-supplied view object with one of your own. And here's the trick: make sure the view outlet (supplied by the UIViewController superclass) is connected to a view. Once this is done, this view will be automatically loaded when your NIB is loaded. You can then just put your UIViewController subclass (Test5ViewController) in your MainWindow.xib NIB file to get it automatically loaded, and you're in business.
Now, the way you're doing it here is the second way. Some people like to code this way all the time and not user interface builder. And while it's definitely necessary sometimes and always more flexible, it makes you understand what is happening a bit better. There may be other things, but the main thing you're missing is that in your code above, you have nothing that is adding your view into the view hierarchy. You need to check first that you have an UIApplicationDelegate subclass and it needs to load your "root" UIViewController class. All initial project creation types in xcode do this (except Window-based application). It is code like:
[window addSubview:rootController.view];
Once this is done, if your view controller wasn't loaded by the NIB (described briefly above), your loadView method will be called, expecting you to build your own view hierarchy. Above, you created the view(s), but failed to put them in a hierarchy. You need something like:
[self.view addSubview:curImage.view];
No view will be rendered until added to the view hierarchy. Make sure to look up the UIView class in the documentation and understand the variety of ways to add and remove views to the view hierarchy.
A couple things I should warn you about:
* your code above is leaking. You need to review how objective-C properties work. There's lots on this site about it. More than I have time to write about here.
* don't create a rootView property in the case you have here. There already is one in the superclass (UIViewController). It's just 'view'. Use that for saving your root view.
I hope this helps you get started. It can be bewildering at first, but you'll soon get it going! I recommend building and rewriting and rebuilding a lot of sample code before you do your "real" application. The SDK has many great samples.