创建递归布局

时间:2014-06-17 15:32:49

标签: ios objective-c ios7

我正在创建一个接收动态和递归数据结构的应用程序,即一个元素可以在其中包含一个相同的元素,类似于HTML的DOM。

在这个阶段,我有“简单”元素类型 text date 按钮,其他人喜欢:网格,表格和部分。最后一个,里面的元素可以是结构,比如孩子的东西,例如,网格元素可以有其他网格。

enter image description here

这些模型元素已经通过我收到的JSON构建在框架上,使用了Factory模式。按此顺序,我已经在视图中绘制了一个元素列表。

我的第一个方法是实现一个UICollectionView,但现在我无法将元素属性绘制到其他人身上。 知道什么是解决这个问题的最佳方法吗?始终考虑到应用程序的性能。

提前致谢

2 个答案:

答案 0 :(得分:2)

谨防这种复杂布局中的自动布局。自动布局有成本,场景越多,视野越复杂,所需的费用就越多。添加和删​​除约束代价很高,布局通过本身也很昂贵。

向我看一个相当简单的布局,其中集合视图放置在表视图中。主视图看起来像一个表视图(可以是一个集合,但很简单)。每个元素都是一个单元格。由于您告诉表格查看单元格大小,只要您可以计算大小,就可以在内部拥有任何内容。事实上,我的section元素看起来像主表一样的表。 Grid元素是一个集合视图。您可以将其作为网格视图执行,然后您可以使用更多重用。

我们来看看。首先是简单元素,文本元素,日期元素,标题部分和页脚部分是简单的表格视图单元格或集合视图单元格。表元素对我来说看起来像集合视图,但可以是任何自定义的。网格是具有流布局的集合视图。如果使用集合实现所有内容,则可以为主视图中的文本和日期元素重用相同的类,否则在此处使用集合视图单元格。 Section元素是一个带有表视图的单元格。单元格可以充当表视图的数据源,或者可以有“嵌套表控制器”,单元可以将其用作表视图的数据源。要获取section元素单元格的高度,您可以获取表格视图的内容大小的高度并返回该高度。如果我们进一步考虑,主视图基本上是顶级节元素表。如果选择“嵌套表控制器”根,则主视图控制器可以将其作为主表视图的数据源。

要跟踪嵌套视图控制器(或单元格作为数据源模型)部分中的元素,我建议使用表示数据的数组,并使用枚举来确定类型。这样,您可以设计各种类型,并根据枚举选择单元格标识符。

此后备数据结构的粗略对象表示如下所示:

{
    type: Section
    items: {
        {
            type: Text
            items: {}
        },
        {
            type: Date
            items: {}
        },
        {
            type: Grid
            items: {
                {
                    type: Text
                    items: {}
                },
                {
                    type: Date
                    items: {}
                },
                {
                    type: Text
                    items: {}
                },
                {
                    type: Text
                    items: {}
                },
                {
                    type: Date
                    items: {}
                }
            }
        },
        {
            type: Section
            items: {
                {
                    type: Title
                    items: {}
                },
                {
                    type: Text
                    items: {}
                },
                {
                    type: Grid
                    items: {
                        {
                            type: Text
                            items: {}
                        },
                        {
                            type: Text
                            items: {}
                        },
                        {
                            type: Text
                            items: {}
                        }
                    }
                }
                {
                    type: Text
                    items: {}
                },
                {
                    type: Footer
                    items: {}
                },
            }
        },
        {
            type: Table
            items: {
                ...
            }
        }
    }
}

这为您提供了与上述示例方案相同的示例。

解析这很简单。在顶部,你可以总是假设有一个section元素,或者更好的是,只是迭代顶级项目并使用每个项目的类型,并在cellForRow:中根据类型返回一个标识符,如果是复杂的输入类型,将子项数组传递给单元格,该单元格将执行相同的逻辑,依此类推。

我使用垂直流的表视图,因为它们更容易管理。您也可以使用具有垂直流布局的集合视图。

使用iOS7的表格视图estimatedRowHeight,您甚至无法解析所有内容,只能解析最直接的单元格以进行优化,并在用户滚动时创建越来越多的内容。

答案 1 :(得分:1)

我不是100%肯定你的问题,而是坚持你的'如何创建支持递归的动态布局',我建议以下

  • 创建UIView子类
  • 为其提供模型属性(例如@property GridModel模型)或为其提供带模型的初始化方法(例如initWithModel:(GridModel *)model
  • drawRect方法或初始化方法中,让它根据模型绘制其子视图
  • 在你的代码中,解析json并根据对象的类型初始化这个特殊的子视图并使其绘制
  • 要动态和递归地绘制多个子视图,请跟踪您的y偏移并确保下一个子视图从上一个子视图结束的位置开始

这有意义吗?