Question

I created a storyboard describing how my navigation-flow is supposed to work, and this works just the way its supposed to be.

at one point i use a collection view to display a list of different levels, where you can pick one.

Now i am using a segue to move ahead to the view controller which is supposed to handle the user input. It consist of 2 image views and 1 custom view i implemented.

But i have 2 different kinds of custom views which subclass an abstract version of the same class. They do similar stuff, most of the time but at some points they are different, so i thought i need to put the into separate classes.

With one class i can just let the Storyboard inflate/instantiate the superclass, since it wasn't supposed to be abstract at that point.

Custom Classes

The idea is that i can pass along the level object, when preparing for segue, and the controller automatically binds the matching controller to the custom-view, which should work since i associated the abstract class with the view.

My Problem is, since the Storyboard handles the initialization of the ViewController, i don't know where or how to apply the Factory.

I've done something similar in Android, but im not entirely sure that this is the best or a good approach on iOS at all.

Besides i to just add the controller in code myself, but i am using auto-layout. and the first point at which i was able to figure out the dimensions of the current view and its chilviews is in ViewDidAppear. But if i start adding/resizing my custom view now, it looks shitty. If i add it in Storyboard, it has the proper size right from the beginning since i could attach constraints to it, just the way i did it with the ImageViews.

Id appreciate any help, or hint into the right direction.

EDIT

im fairly certain that MasterDetail like implementation would work, but from what i understand this isn't any different to the version in which i handle the view-controller creation myself. i want the view to get its size by auto-layout, so that when they appear for the first time, they already have the proper size and i don't have to resize them after already displaying them.

Which raises the Question, can i add a View in Storyboard without a ViewController, and just attach the ViewController to the view in code?

Is that a bad idea?

Was it helpful?

Solution

There are a few options, based on exactly what your controller and view classes are doing:

1.

Stick with what you suggested, but rather than specify a particular view subclass in the storyboard, instead just add a 'container' view there (simple UIView). This view has all of your required constraints. Now, rather than binding a controller to an existing view, create a controller and associated view based on the level content. Add the view to the 'container' view and simply pin it to the superview edges.

2.

By specifying the name of your 'abstract' class in the storyboard, that is the type of instance you get. Technically you could replace it after the view has loaded and transfer all of the constraints.

3.

Rather than using a view controller factory, you could move the implementation of both of your view subclasses into a single class and either add logic to do different things in each method or use an object state pattern to change the internal implementation.

OTHER TIPS

This is the stock implementation of Apple's Master-Detail Application template when selecting an item on the Master view controller and showing it in the detail view controller (possibly with a push segue):

From Master View Controller:

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

    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        NSDate *object = _objects[indexPath.row];
        self.detailViewController.detailItem = object;
    }
}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"showDetail"]) {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        NSDate *object = _objects[indexPath.row];
        [[segue destinationViewController] setDetailItem:object];
    }
}

From Detail View Controller:

- (void)setDetailItem:(id)newDetailItem {
    if (_detailItem != newDetailItem) {
        _detailItem = newDetailItem;

        // Update the view.
        [self configureView];
    }

    if (self.masterPopoverController != nil) {
        [self.masterPopoverController dismissPopoverAnimated:YES];
    }        
}

- (void)configureView
{
    // Update the user interface for the detail item.

    if (self.detailItem) {
        self.detailDescriptionLabel.text = [self.detailItem description];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self configureView];
}

I would think you could do something similar for yourself, where you set a property on the segue.destinationViewController. Basically, make your own configureView method that sets up the view correctly based upon the object you've assigned to the UIViewController.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top