为场景设置母版页

时间:2014-02-18 17:11:07

标签: ios objective-c storyboard interface-builder

注意:我不是在谈论Master-Detail SplitViews!

有一个与此类似的问题(Master page concept in Iphone development),但问题仅涉及标准功能,而不是布局本身。此外,答案仅显示如何避免重复代码,但您仍需要在每个场景上链接IBActions。也许我们可以扩展相关问题并发现一些更好的解决方案: - )

所以,我想为我的应用程序中的所有场景/视图控制器定义一个母版页。这是Web开发中的常见任务(即ASP.NET Masterpages)。

母版页将包括实际布局(背景颜色,标题所在的位置,内容所在的位置等)以及所有场景中的标准功能(打开菜单,返回,打开帮助页面等)< / p>

使用Interface Builder(有或没有Storyboard),最好的方法是什么?

以下是我的想法:

选项1:用于标准功能的子类UIViewController,在每个场景/视图控制器中复制通用布局。

优点:相当容易使用,只需复制所有控件,在IB中设置父类并连接标准功能按钮。

缺点:如果您有大量场景,则很繁琐,您很容易忘记连接标准功能。如果主布局因任何原因发生变化,那就搞砸了。

选项2:子类UIViewController,以编程方式在viewDidLoad中的某处添加布局,您还可以在其中设置事件目标

优点:布局和功能都在一个地方处理,并且可以轻松更改。

缺点:您需要以编程方式设置布局,如果您在其他地方使用IB,则不一致。您没有在IB中看到主布局,因此您必须在IB中配置其余场景时“想象”它。 如果没有Storyboard,您可以使用XIB仅设计内容视图,但之后您永远不会拥有IB中的“整体图片”。此外,这不适用于Storyboard。

这两个选项对我来说似乎都不优雅。你做什么的方法(这必须是一个常见的问题!)?

2 个答案:

答案 0 :(得分:1)

有很多方法可以做到这一点。我喜欢的两种方式跟随。

在两者中,你都是从(使用你的术语)MasterVC开始的。为共同元素做所有布局和设计。然后对于contentView,要么:

  1. 放入单独的视图,并以编程方式添加childViewControllers;或
  2. 放入一个包含UICollectionView的containerView。在collectionView中创建一个占用整个collectionView的单元格。创建一个带有一个插座的自定义单元类(在我的示例中为pageView),并以两种方式之一从Storyboard加载ViewControllers。将VC的标识符设置为表示它们在collectionView中出现的位置的数字,或者创建VC名称数组。然后,只要用户导航到某个VC,就告诉collectionVC滚动到该索引。
  3. cellForItemAtIndexPath中的实现看起来像这样:

    - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
    {
        AMMasterCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath ];
    
        for (UIView *view in cell.pageView.subviews)
            [view removeFromSuperview];
    
        NSString *viewID = self.arrayOfViewControllerNames[indexPath.item];
    
        AMMasterViewController *viewController = [self.storyboard instantiateViewControllerWithIdentifier:viewID];
        AMMasterView *pageView = (AMMasterView *)viewController.view;
        [cell.pageView addSubview:pageView];
    
        [self addChildViewController:viewController];                 
        [viewController didMoveToParentViewController:self];
    
        return cell;
    }
    

    我已经做过很多次了,而且效果很好。

答案 1 :(得分:0)

如果您的标准布局包含通过IBOutlets链接到您的代码的创建控件,那么您只有两种方法可以在故事板上或以编程方式添加它们。逻辑到目前为止。

现在我会考虑这个问题。如果您的所有视图都具有相同的控件(不太可能),那么您可以在故事板中构建一个视图并生成它。在更合乎逻辑的情况下,他们共享一系列控件,并且您希望标准化那些您有三个选择。

  1. 您在故事板中构建标准设计,并以编程方式添加每个视图中所需的控件
  2. 您以编程方式构建标准设计并在storyboard中添加其他控件
  3. 以编程方式执行所有操作
  4. 我很可能会选择选项2并以这种方式组织:

    1. 创建一个功能setupView来设置标准设计
    2. 在视图中使用我将调用[whereEverYouPutThis setupView];
    3. 的设计加载每个视图

      使用此选项,您可以非常快速地在一个地方对主人进行更改,并且您可以使用故事板来制作特定于视图的内容。