UIView's initWithFrame not working? - iphone

i set my view controller to the particular view through Interfacebuilder.
but initWithFrame is not calling , but drawRect is being called?when i put break point?

Right, because it's not guaranteed that initWithFrame: will be called when unarchiving the xib. Try using awakeFromNib or viewWillLoad or viewDidLoad. Which one you choose will mainly depend on at what stage during the display process you need to insert your code.
Also, check out the answer to this question.

According to the documentation - http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html - initWithFrame: is not called when your view objects are subsequently loaded from the nib file. Objects in a nib file are reconstituted and then initialized using their initWithCoder: method, which modifies the attributes of the view to match the attributes stored in the nib file.

Related

How to add the UI for one of the tab controller's using loadView when the rest were via Interface Builder?

I have a main window which has the UITabViewController as its root controller. I am using a nib file for this. In Interface Builder, two of the tabs have been wired to Controller_A, Nib_A and Controller_B, Nib_B but the 3rd tab only knows about Controller_C.
I assumed that this would mean that the loadView method of Controller_C would be automatically called since I haven't bothered to specify the NIB file. I want to lay this piece out programmatically. And it DOES indeed get called as I've confirmed by placing a breakpoint inside this method.
BUT when I switched over to Controller_C in the simulator, it comes up empty!
Here's what the loadView of Controller_C looks like:
- (void)loadView
{
[super loadView];
...
[self setTableView:formTableView];
[view addSubview:formTableView];
[self setView:view];
}
Any tips? What am I ignoring?
Looks like you are searching for:
-(void)viewDidLoad {
Here are the main things to check.
Click on your Controller_C in interface builder. In the Identity Inspector, make sure that the Class field is set to Controller_C.
In the Attributes Inspector, make sure the NIB Name field is blank.
If you have an existing Controller_C.xib laying around in your project, remove and delete it. The default implementation of loadView loads this file even if
Remove [super loadView]. Since you're building your view hierarchy in code, you shouldn't invoke the default implementation. You should explicitly allocate the controller's view as a local variable in loadView and set it using setView:.
Also, your comment on the other answer suggests that you may be confused about when/why loadView and initWithNibName:bundle: get called, so let me clarify:
loadView gets called to lazy load your controller's view the first time its view property gets accessed. This is true whether your view controller was constructed as an object in a NIB, or whether you constructed it yourself in code using initWithNibName:bundle:. The default implementation of loadView loads the NIB that was specified in initWithNibName:bundle: or in the NIB Name property in IB. If a NIB name wasn't specified, the default implementation looks for any NIB in the bundle that has the same name as your class and loads that NIB if one is found. If no appropriate NIB is found, then the default implementation of loadView just creates an empty view and sets that as your controller's view. When we build our own view hierarchy explicitly in loadView, we don't want any of these default behaviors, so we don't call [super loadView].
It seems loadView works as expected, the reason that my view was blank is because the datasource for my tableview was actually NIL. Earlier, I did not consider this scenario as I thought that it would at least present an empty table in such a case but apparently that was an incorrect assumption on my part. All this mistakenly led me to believe that the view wasn't being initialized properly.
#cduhn: Thanks, I had been following steps 1-3 already and it was really good to hear someone else give the same advice. The rest of what you said was educational for me as well.
Thanks Everyone.

UIImageView Created In Interface Builder Set To nil When Needed

I have an application where small number of objects are defined in the MainWindow. A pair of these objects are a UIViewController and the UIImageView that goes along with this controller. When the application starts up, the entire MainWindow.xib get loaded & I can see that this UIImageView has been loaded into memory. At this point, I have no need for this UIImageView.
When I need the UIViewController, I perform the usual alloc/init setup. At this point, when I look at this controller with the debugger, the controller is setup correctly, but the UIImageView that should have been pre-wired with Interface Builder is always nil.
Any suggegstions on how to make sure this UIImageView is loaded into memory correctly? This is the only case where I've had an issue with objects defined within this single MainWindow.xib file.
Assuming you have connected the view outlet, all you need to do is access the view property. When you look in the debugger, you're seeing the property's corresponding ivar. When you access the property in code, it should load for you. So, it should be as simple as:
[controller view];
Not quite sure I understand the problem, but instead of having the UIImageView in MainWindow.xib, why not have it in the xxxViewController.xib where it's actually going to be needed?

IBOutlet UIView loaded from a Nib file

I am loading a UIView from a NIB file with outlets and I want to change the properties of these outlets. I am wondering when I should do that because in the init method the outlets are nil and that make sense and in the drawRect method I can change the properties of my outlets but I'm not sure it's the proper way to do that.
Is there a method called after the init method and the drawRect method where I could do what I want ?
Thank you.
There's layoutSubviews - this will definitely be called before the first call to drawRect?
The UIViewController method viewDidLoad is called after a nib has been loaded and after loadView is called. (loadView allows you to load a view programmatically instead of using a nib. However, nibs are much better so it's best to pretend that loadView doesn't exist.)
NSObject implements awakeFromNib. awakeFromNib is called after an object has been loaded from a nib. Here's a quote from the docs:
Typically, you implement awakeFromNib for objects that require additional set up that cannot be done at design time. For example, you might use this method to customize the default configuration of any controls to match user preferences or the values in other controls. You might also use it to restore individual controls to some previous state of your application.
drawRect: is a UIView method, only use it if you need to do Quartz drawing. Using layers and Core Animation is more efficient. If you want to configure a custom UIView (i.e. you've subclassed UIView instead of configuring a view within a UIViewController) then you should use initWithCoder:.
If you want to use IBOutlets in your initialization code for a UIView - override awakeFromNib. This is the first method called after outlets have been configured.
With regard to UIViewController - viewDidLoad and viewDidAppear are often convenient locations to put your initialization code in but beware: autolayout has not happened at this stage which means strange autoresizing effects can cause you bother. The better solution is to put your code in viewDidLayoutSubviews which is the first lifecycle method called after autolayout.

What is the difference between loadView and viewDidLoad?

I know there is a seemingly exact duplicate of this question here: iPhone SDK: what is the difference between loadView and viewDidLoad?
However, I have read that question and still it was not fully answered.
I'm not using IB as the UI is dynamic.
So should I create the self.view and then add the subviews in loadView,
or should I create the self.view in loadView and add the subviews in viewDidLoad?
When you load your view from a NIB and want to perform further customization after launch, use viewDidLoad.
If you want to create your view programatically (not using Interface Builder), use loadView.
For your specific question, you should add the subview in viewDidLoad. Because, if you overwrite the loadView, you have to do all the jobs, loading all the views.
Here is the explanation from Apple's documentation:
The steps that occur during the load cycle are as follows:
1.
* Some part of your application asks for the view in the view
controller’s view property.
2.
* If the view is not currently in memory, the view controller calls its loadView
method.
3.
* The loadView method does one of the following:
If you override this method, your implementation is
responsible for creating all
necessary views and assigning a
non-nil value to the view property.
If you do not override this method, the default implementation uses
the nibName and nibBundle properties of the view controller to try to load the view
from the specified nib file. If the
specified nib file is not found, it
looks for a nib file whose name
matches the name of the view
controller class and loads that file.
If no nib file is available, the method creates an empty UIView object
and assigns it to the view property.
4.
* The view controller calls its viewDidLoad method to perform any
additional load-time tasks.
It is very simple actually. If you do it without IB, then your UIViewController's view property is empty. So set it at loadView!
I only do setting of view at loadView and nothing else.
Other than that, do all thing inside viewDidLoad. Here is some example:
- (void)loadView {
CGRect frame = [[UIScreen mainScreen] applicationFrame];
baseView = [[UIView alloc] initWithFrame:frame];
[self setView:baseView];
[baseView release];
}
That's it! I am done. And would never want to add more to it. Then at the viewDidLoad, I add all those subviews I want to.
- (void)viewDidLoad {
[super viewDidLoad];
msg = [[UILabel alloc] initWithFrame:CGRectMake(0, 200, 320, 50)];
[msg setText:#"Your profile is empty!"];
[[self view] addSubview:msg]; // hey, I have done my view at loadView, so I have it now
[msg release];
}
I could be wrong in my understanding :)
loadView is the method that actually sets up your view (sets up all the outlets, including self.view).
viewDidLoad you can figure out by its name. It's a delegate method called after the view has been loaded (all the outlets have been set) that just notifies the controller that it can now start using the outlets.
viewDidLoad:
"This method is called after the view controller has loaded its associated views into memory. This method is called regardless of whether the views were stored in a nib file or created programmatically in the loadView method."
loadView:
"If you create your views manually, you must override this method and use it to create your views."
Add subviews in viewDidLoad. That way you are 100% sure than the view did indeed load and is ready for consumption.
Use viewDidLoad for initialize views and constrols. And use loadView if you don't have Nib/Xib and would like your ViewController has custom (not UIView) view.
Only use loadView when you want to create a view yourself.
Don't use loadView after you use interface builder or init with nib since these actions have already called loadView in the underly implementation.
Also, when use loadView, assign view first before doing any other settings:
-(void)loadView {
[super loadView];
// if you do any things here before assigning a view
// it will try to get a view first by calling loadView()
// and ends up with a crash since a dead loop.
self.view = ...;//assign your view here
//do other settings
}

whats the different between nibNameOrNil and ViewDidLoad methods?

whats os the difference between initWithNibName and ViewDidLoad methods ?
can i use them both?
initWithNibName - is what you call to create a view controller from specified nib file.
viewDidLoad - is what system calls on your controller after the controller’s view is loaded into memory. You can implement this method to perform some additional initialization (which is not done in nib file)
I think you may be confusing things here. nibNameOrNil is (usually) an argument name, frequently for -initWithNibName:bundle:. As such, it should be the name of your nib (.xib) file. -viewDidLoad is a method, and is called after your viewController has had it's view instantiated for the first time.