Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: how to create views programatically using XIB, but without using View Controller

I am trying to fill a scroll view with a number of subviews that are identical, except the data changes. If I want to do the whole thing programatically, I can, like so:

int width = 110;
int count = 0;
self.scrollView.contentSize=CGSizeMake(width*[items count],100);

for (NSString *id in items) {
    Item *item = [items objectForKey:id];
    CGRect frame = CGRectMake(count*width, 0, 100, 100);
    UIView *itemSubview = [[UIView alloc] initWithFrame:frame];

    CGRect dataLabelFrame = CGRectMake( 0, 52, 35, 30 );
    UILabel* dataLabel = [[UILabel alloc] initWithFrame: dataLabelFrame];
    dataLabel.text = @"Data specific to item"; // item.property or something
    dataLabel.font:[UIFont systemFontOfSize:30];
    dataLabel.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];

    [itemSubview addSubview:dataLabel];
    [self.scrollView addSubview:itemSubview];
    [itemSubview release];
}

All good. Now, how do I do the same thing if my subView is a little more complex, and I want to lay it out with Interface Builder and a xib archive? So far I have:

  • created my own custom view code, ItemSubview, extending UIView with an IBOutlet NSString *dataLabel
  • created my xib file, set the file's owner to be of class ItemSubview, and hooked up my label to the outlet

then, in code:

int width = 110;
int count = 0;
self.scrollView.contentSize=CGSizeMake(width*[items count],100);

for (NSString *id in items) {
    Item *item = [items objectForKey:id];
    CGRect frame = CGRectMake(count*width, 0, 100, 100);
    ItemSubview *itemSubview = [[ItemSubview alloc] initWithFrame:frame];
    [itemSubview setBackgroundColor:[UIColor colorWithRed:0.0 green:0.2 blue:0.0 alpha:0.2]]; // to see where it ends up

    [[NSBundle mainBundle] loadNibNamed:@"ItemSubview" owner:itemSubview options:nil];
    itemSubview.dataLabel.text = @"Data specific to item"; // item.property or something
    [self.scrollView addSubview:itemSubview];
    [itemSubview release];
}

When I do this, my itemSubview gets drawn (I can see the background color of the itemSubview), but not the dataLabel that was in the xib archive. What am I missing/not understanding? Why does this work programatically, but not with a xib file?

like image 871
meriial Avatar asked Aug 31 '12 05:08

meriial


People also ask

How do I create a view programmatically in Swift?

Creating UIView Programmaticallylet myNewView=UIView(frame: CGRect(x: 10, y: 100, width: 300, height: 200)) // Change UIView background colour myNewView. backgroundColor=UIColor. lightGray // Add rounded corners to UIView myNewView. layer.

Should I use XIB or storyboard?

If you are a single developer, it is good to use storyboard because it consumes less time. If the team consists of many developers, use xib, otherwise, it is not easy to merge the modules/tasks.

What is difference between XIB and NIB?

In fact, the acronym "NIB" comes from "NeXTSTEP Interface Builder", and "XIB" from "Xcode Interface Builder". NIBs and XIBs are effectively the same thing: XIBs are newer and are used while you're developing, whereas NIBs are what get produced when you create a build.


1 Answers

Do it like this:

    NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"ItemSubview" owner:self options:nil];
    ItemSubview *itemSubview = [topLevelObjects objectAtIndex:0];

Make sure that in your xib file, the top level view is of class ItemSubview, and that dataLabel is properly hooked up to ItemSubview's outlet. File's owner should be left blank.

like image 94
Darren Avatar answered Oct 17 '22 18:10

Darren