3
votes

I have a question about UIViewController's subview, I created a UIView subclass MainView, which has the exact size of the screen, I wonder which is a better way of adding MainView, consider the following factors:

1 As MainView has same size as the whole screen, the MainView itself may have subviews, but there is no views at the save level as MainView(ie I don't need to add other subviews to self.view).

2 If I use self.view = mainView, do I put the code in loadView(as the viewDidLoad method means the view(self.view) is already loaded)? I see the loadView method is commented out by default, if I add the code to this method, what other code do I need to put together(e.g. initialize other aspects of the application)?

3 If I add mainView via [self addSubview:mainView], are there actually two off screen buffer? One for self.view, one for mainView, both has same size as the screen and one is layered on top of the other(so it wastes memory)?

Thanks a lot!

5

5 Answers

2
votes

I'm not sure I completely understand what you're asking, but I'll try to answer a few of the questions you have.

First of all, if you have multiple UIViews on the screen they are all loaded into memory. You have to do -removeFromSuperview and release them to get the memory back.

You can assign your UIView as the UIViewController's view. For example:

MainView *mainView = [[MainView alloc] initWithFrame:CGRectMake(320.0, 480.0)];
self.view = mainView;
[mainView release]; //since the .view property is a retained property

in that case, you have have the view's initialization code in the -init method. Just redefine it like:

- (id)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
              //initializations
        }
        return self;
}
1
votes

I'd solve all of this by doing it in a xib! If you create a UIView in your xib, you can then change it's class (when you select the UIView there should be a text field in the Class Identity section of the Identity inspector* - type 'MainView' here!)

Then, create your view controller by calling

myViewController = [[MainViewController alloc] initWithNibName:@"MyNibName" bundle:nil]; 

That should solve your problems; it's the main subview of your view controller (directly accessable from self.view) and you don't need to worry about memory usage, there's only one view :)

Sam

NB * Click tools -> Identity Inspector. I didn't know it was called this until I had to write this answer!

1
votes

You must implement loadView if you did initialize your view controller with a NIB.

UIViewController takes care of sizing its "main" view appropriately. This is all you need to do:

- (void)loadView
{
    UIView* mainView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
    self.view = mainView;
}
0
votes

Yes, the first code-snippet shown above is the "standard" approach, AFAIK, when not using (evil!) NIB files -- i.e. when alloc'ing your view in-code, via loadView.

Note it seems one can also get away with the following, instead of hard-coding the screen-rect size:

UIView *myView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; 
self.view = myView; 
[myView release];

Note you definitely want to do the [myView release] call since, indeed, as pointed out above, self.view (for UIView) is a retained property.

Cheers, -dk

0
votes

Perhaps the most important thing to do is make sure you have the following:

self.view.userInteractionEnabled = YES;

While it might not be required all of the time, it fixes the issue where self.view is unresponsive. This issue pops up occasionally.