I externalized a component in a XIB file so I can reuse it in several different views. Now in my view controller I load the XIB-based UIView and add it to the current view through :
NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"ThumbsPreviewView" owner:self options:nil];
_likePreview = [views objectAtIndex:0];
[self.view addSubview:_likePreview];
At first, I thought that it was not working... but actually it works but only put the root view (i.e. the container of all my graphical components, which is transparent) to my view.
So I need to put this kind of code (for every sub component) to make it work :
[self.view addSubview:_likePreview];
NSArray *subviews = _likePreview.subviews;
for(UIView * subview in subviews) {
[self.view addSubview:subview];
}
This is very counter-intuitive, and moreover I think it does not create the view hierarchy that I would like.
I am sure there is a solution because I did the same kind of thing in a UITableViewController to load a custom table header from a XIB. Using the exact same XIB file in this situation loads everything properly. Here is the code :
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
switch(section) {
case 0: {
NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"ThumbsPreviewView" owner:self options:nil];
_likePreview = [views objectAtIndex:0];
return _likePreview;
}
}
return [super tableView:tableView viewForHeaderInSection:section];
}
With the above code, everything is fine, I got the whole view (= root view container with all its content) as the header of my table section.
So the question is : what am I doing wrong in my first example ? How can I add all content (container + all content) to my parent UIView as a proper UIView hierarchy ?
EDIT : I need to precise that everything is organized in my XIB file in a single root UIView, as follows (I cannot post image) :
* Thumbs preview view
|_ Button
|_ Image View
|_ Image View
|_ Image View
|_ Image View
|_ Button
|_ Button
|_ Button
|_ Label
Thank you very much for your help !
Christophe
One way to load your component is to store your components into a top UIView
object (s. attached screenshot).
(source: mobypicture.com)
You can then load your nib as usual and use -addSubview:
to add your components to the view hierarchy.
EDIT:
Loading the nib with
UIView *view = [[[NSBundle mainBundle] loadNibNamed:@"testView" owner:self options:nil] objectAtIndex:0];
and adding the view to the view hierarchy with
[self.view addSubview:view];
leads to the following view hiearchy:
(lldb) po [[self view] recursiveDescription]
(id) $1 = 0x088487b0 <UIView: 0x89595b0; frame = (0 0; 320 548); autoresize = W+H; layer = <CALayer: 0x8958b30>>
| <UIView: 0x89755c0; frame = (0 0; 320 200); autoresize = RM+BM; layer = <CALayer: 0x8975080>>
| | <UIView: 0x8975620; frame = (200 20; 100 30); autoresize = W+H; layer = <CALayer: 0x8975680>>
| | <UIView: 0x8975700; frame = (20 20; 100 30); autoresize = W+H; layer = <CALayer: 0x8974ea0>>
| | <UIRoundedRectButton: 0x8975790; frame = (20 58; 73 44); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8975890>>
| | | <UIGroupTableViewCellBackground: 0x8976030; frame = (0 0; 73 44); userInteractionEnabled = NO; layer = <CALayer: 0x8976100>>
| | | <UIImageView: 0x89768d0; frame = (1 1; 71 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x89770f0>>
| | | <UIButtonLabel: 0x8977af0; frame = (36 22; 0 0); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8977be0>>
| | <UIRoundedRectButton: 0x8978990; frame = (227 58; 73 44); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x8978a60>>
| | | <UIGroupTableViewCellBackground: 0x8978a90; frame = (0 0; 73 44); userInteractionEnabled = NO; layer = <CALayer: 0x8978b10>>
| | | <UIImageView: 0x8978b80; frame = (1 1; 71 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8979230>>
| | | <UIButtonLabel: 0x8978be0; frame = (36 22; 0 0); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x8978cd0>>