Nosrettap
Nosrettap

Reputation: 11320

How to display a complex UIViewController inside another UIView Controller?

Ok, so here's the situation. I currently have a view controller called MainViewController which has a UITableView with many different cells. When I click on a cell, I want that cell to expand (grow in height) and show some "additional information". The problem is, this additional information is very complex and can contain UILabels, other UITableViews, UIWebViews and UIImageViews. Furthermore, this "additional data" requires quite a bit of computation in order to determine what exactly to display (i.e. what the UILabels say, how large the UIImageViews are). Therefore, because of the complexity of this "additional information", I'm at a loss as to how to design my program.

The "additional information" requires a lot of code, thus I don't want to just throw that code into the MainViewController. Additionally, it would be nice if there was some way to use Interface Builder to design these "additional information" views graphically rather than programatically.

Currently I have each set of additional information as its own separate UIViewController (thus allowing me to have separate classes for the data and allowing me to use interface builder) and I just segue to a new screen when a cell is selected. However, I don't want to segue to a new screen; I want all of the data that this UIView controller is showing to be shown in MainViewController. What's the best way to do this?

In summary, I currently have one UIViewController segueing to another UIViewController; however, I want the second UIViewController's content to be show in the first. If possible I would like to use some sort of Interface Builder and to separate out the logic for this second UIViewController into another class.

Details: ~ I'm developing for iOS 5 only and I'm using ARC. ~ I've never developed for iOS 4 or below before and I have never used nib files before but I would be willing to learn if required. Simple sample code would be helpful. ~ Thanks!

Upvotes: 1

Views: 2155

Answers (4)

jlehr
jlehr

Reputation: 15597

There are some good suggestions here, but note that loadNibNamed:owner: is a fairly expensive API to call repeatedly because it reads the nib from the filesystem each time. Instead, consider doing something like this.

Register your nib file in viewDidLoad. In Interface Builder, make sure to provide a reuse identifier for your custom cell.

- (void)viewDidLoad
{
    [super viewDidLoad];

    UINib *myNib = [UINib nibWithNibName:@"MyNib" bundle:nil];
    [self.tableView registerNib:myNib forCellReuseIdentifier:@"MyCell"];

    // Do any other stuff you need to do...
}

Then just dequeue your custom cell whenever you need it. UINib will cache the nib file in memory to avoid reloading it from the filesystem each time.

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];

    // Configure cell as needed...

    return cell;
}

Upvotes: 2

Shyam Bhat
Shyam Bhat

Reputation: 1600

Just to add to what SmartWork said, when you tap a particular cell, you can update the height of that row using the following lines of code:

- (CGFloat)tableView:(UITableView *)aTableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
     // set a dynamic value for the cell height depending on the state of the data in the cell 
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

    // update the state of the data in the cells here..  
    // calling these below lines will change the height of the cells smoothly 


    [tableView beginUpdates]; 
    [tableView endUpdates]; 

}

You will also need custom UITableViewCells. Look at them as simple views and add and remove any number of subviews that you need

If you are keen on using Nibs for your subviews inside the cells, you can create their nibs and connect them to your Custom TableView Cells as follows: (The subviews can be properties of your tableViewCell)

NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:@"MyTableViewCellNib" owner:self options:nil];

mySubview = [(SubView *)[nib objectAtIndex:0]retain];

Upvotes: 1

Martin
Martin

Reputation: 12215

Same opinion as SmartWork.

You should create your custom UITableViewCell class with its xib file, with a UITableViewCell as main xib view

And in your tableView datasource, you can import it as below :

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MyViewCell";
    MyViewCell *cell = (MyViewCell *)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"MyViewCell" owner:nil options:nil];
        for (id currentObject in topLevelObjects) {
            if ([currentObject isKindOfClass:[UITableViewCell class]]) {
                cell = (MyViewCell *)currentObject;
                break;
            }
        }
    }
    [self configureCell:cell atIndexPath:indexPath]; // your own function to customize your cell.
    return cell;
}

Then, in the cell xib, you can set the max height of the cell, and decide the effective height in the UITableViewDelegate class.

Upvotes: 2

freelancer
freelancer

Reputation: 1658

in my opinion there is no need of using one UiviewController inside another.

u can use Uiview with nib file so u can design these "additional information" views graphically. its very easy to implement and maintain it.

Upvotes: 1

Related Questions