故事板和ViewController工厂

时间:2014-03-14 13:38:35

标签: ios uiviewcontroller uistoryboard factory-pattern

我创建了一个故事板,描述了我的导航流应该如何工作,这就像它应该的那样工作。

在某一点上,我使用集合视图来显示不同级别的列表,您可以在其中选择一个。

现在我正在使用segue向前移动到应该处理用户输入的视图控制器。它由2个图像视图和1个自定义视图组成。

但我有两种不同的自定义视图,它们是同一类的抽象版本的子类。他们做类似的事情,大部分时间,但在某些时候他们是不同的,所以我认为我需要把它分成不同的类。

使用一个类我可以让故事板膨胀/实例化超类,因为那时它不应该是抽象的。

Custom Classes

我的想法是,当准备segue时,我可以传递关卡对象,并且控制器会自动将匹配的控制器绑定到自定义视图,这应该可以工作,因为我将抽象类与视图相关联。

我的问题是,由于故事板处理ViewController的初始化,我不知道应用工厂的位置或方式。

我在Android中做过类似的事情,但我并不完全确定这是iOS上最好或最好的方法。

除了我自己只是在代码中添加控制器,但我正在使用自动布局。我可以在ViewDidAppear中找到当前视图及其chilviews的尺寸的第一个点。但是,如果我现在开始添加/调整我的自定义视图,它看起来很糟糕。如果我在Storyboard中添加它,它从一开始就具有适当的大小,因为我可以附加约束,就像我使用ImageViews一样。

我感谢任何帮助,或暗示正确的方向。

修改

我相当确定MasterDetail之类的实现是可行的,但据我所知,这与我自己处理视图控制器创建的版本没有任何不同。我希望视图通过自动布局来获得它的大小,这样当它们第一次出现时,它们已经具有适当的大小,并且在显示它们之后我不必调整它们的大小。

提出问题,我可以在没有ViewController的情况下在Storyboard中添加View,只需将ViewController附加到代码中的视图中吗?

这是个坏主意吗?

2 个答案:

答案 0 :(得分:1)

根据控制器和视图类的具体操作,有几个选项:

1

坚持你的建议,而不是在故事板中指定一个特定的视图子类,而只是在那里添加一个“容器”视图(简单UIView)。此视图具有所有必需的约束。现在,不是将控制器绑定到现有视图,而是根据级别内容创建控制器和关联视图。将视图添加到“容器”视图中,然后将其固定到超视图边缘。

2

通过在故事板中指定“抽象”类的名称,即您获得的实例类型。从技术上讲,您可以在视图加载并替换所有约束后替换它。

3

您可以将两个视图子类的实现移动到单个类中,并添加逻辑以在每个方法中执行不同的操作,或者使用对象状态模式来更改内部实现,而不是使用视图控制器工厂。 / p>

答案 1 :(得分:0)

在主视图控制器上选择一个项目并在详细视图控制器中显示它时,这是Apple的Master-Detail Application模板的库存实现(可能带有推送segue):

来自主视图控制器:

- (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];
    }
}

来自详情视图控制器:

- (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];
}

我认为您可以为自己做类似的事情,在segue.destinationViewController上设置属性。基本上,制作您自己的configureView方法,根据您分配给UIViewController的对象正确设置视图。