大家好,我是姜友华,前面两章我们实现了两类视图,一个是标签视图,一个是分割视图。这一节我们来实现布局的控制。
在进行布局控制之前,我们先来了解一下布局。
一、布局的设定。
上图是我们对当前应用进行的布局设定,它有以下特征。
- 布局是由分割视图(SplitView)和标签视图(BlockView)组成,前者为枝节点,后者为叶节点。
- 每一个BlockView会加载一组功能视图。
- 每个SplitView必须至少包含有一个BlockView,如果没有,则该SplitView可被移除。
二、 数据的设定。
1)数据的定义。
通过布局的设定,我们可以理解为布局是加载一组树状结构的数据。所以我们将这下数据抽取出来,表现如下:
struct Layout: Codable {
static func == (lhs: Layout, rhs: Layout) -> Bool {
return lhs.id == rhs.id
}
var id = Date.id
var children: [Layout] = [] // 为空时为叶节点
var kind: Kind = .hSplit
var bar: Bar = Bar()
var length: CGFloat? = nil
enum Kind: Codable, Equatable, Hashable {
case hSplit // 横的
case vSplit // 竖的
case chapter // 章节窗口
case assist // 辅助功能窗口
}
struct Bar: Codable, Equatable, Hashable{
var tags: [Int] = [0]
var current: Int = 0
}
}
-
id、kind、bar、length
,都是附加数据。分别表示创建的时间、视图的类型、占宽或高等信息。 -
children
,表示为布局视图的子节点。 -
kind
,表示叶节点加载的视图的类型。暂时定义了4种:-
hSplit
水平分割的视图; -
vSplit
垂直分割的视图; -
chapter
章节视图; -
assist
辅助功能视图。
-
-
Bar
结构体,需要说明一下。- tags,打开的标签。
- current,当前的标签。
2)对应用的视图。
- LayoutView,对应用
kind = hSplit
或kind = vSplit
, 加载layout,并实现布局的分割与嵌套, 与其实类型的实例化。 - ChapterView,对应用
kind = chapter
, 加载章节内容。 - AssistView,对应用
kind = assist
, 为辅助功能视图。具体到每个辅助功能,则都有自己的视图,暂定的有:
- CatalogView,目录。
- MindView, 导图。
- ReminderView,备忘。
- SymbolView,符号。
- CollectView,收藏。
- SearchView,搜索。
- Layout数据示例:
let layout: Layout = Layout(
children:[Layout(
kind: .assist,
bar: Layout.Bar(tags: [0], current: 0),
length: 200
),Layout(
kind: .chapter,
bar: Layout.Bar(tags: [0], current: 0),
length: 400
),Layout(
kind: .assist,
bar: Layout.Bar(tags: [1,2,3,4,5], current: 1),
length: 400
)],
kind: .hSplit
)
我们定义一个layout,它水平显示3栏:
- 加载目录,宽200;
- 加载文章,宽400;
- 加载其它辅助功能,宽400.
需要注意的是,首先,为什么是宽?因为这是水平的kind: hSplit
布局,如果是垂直的布局则为高;其次,为什么第一栏加载的是目录?因为我们初始化了一组辅助功能数据。
let assists = [
Assist(kind: .catalog),
Assist(kind: .mind),
Assist(kind: .reminder),
Assist(kind: .symbol),
Assist(kind: .collect),
Assist(kind: .search)
]
运行一下,看看效果。
三、操作的设定。
从布局的设定可以看出,界面的表面会被ChapterView
或AssistView
所覆盖,也就是说,我们无论将标签拖到哪个位置,其下必然有ChapterView
或AssistView
。因此我们只需要在ChapterView
或AssistView
上对拖移作反应即可。这种反映叫热区反映。
热区分上下左右中和顶部,其中顶部为标签栏。
- 左、右热区。表示随标签移动的
FunctionView
将与热区BlockView
水平排列,并放置其左或其右。 - 上、下热区。处理逻辑同上,位置为其上或其下。
- 中、顶热区。表示随标签移动的
FunctionView
将加入到热区BlockView
里,作为标签方式呈现。 - 经过左热区时,
BlockView
视图区左则显示蒙版。右、上、下如之类推。 - 经过中热区时,
BlockView
视图区显示全蒙版。 - 经过顶热区时,
BlockView
标题区显示位置蒙版。
好,这一节就这些,我是姜友华,下次见。