YXMenuView 开发小记

第一次尝试做一个 iOS Framework - YXMenuView[1],遇到了不少问题,写这篇来记录遇到的一些问题以及 MenuView 的设计思路。

基本结构

MenuView 分为两部分:

  • headerView (custom view)
  • bodyView (table view)

初始化问题

VIew 初始化的大致流程

  1. init(frame: CGRect) 或者 init?(coder aDecoder: NSCoder) 初始化基础 View initBaseView(),也就是 View 的大致结构,并且使用默认数据源初始化详细 View
  2. 如果没有设置 Delegate 和 DataSource,到这一步就可以结束了
  3. 当检测到 delegate 或者 dataSource 被设置,通过 didSet 属性方法调用相应函数,重新初始化详细 View
  4. 完成初始化

DataSource 与 Initialization 的顺序问题

当使用 MenuView 的时候需要设置 delegate 和 datasource,一般是在 viewdidload 方法里面调用,在这之前需要先初始化 MenuView ,而初始化需要数据源确定视图布局,这里就凸显出来矛盾之处。

因为需要根据 DataSource 提供的数据源来确定 View 的布局 (sectionView),比如我们拿这个 MenuView 做一个筛选的功能,筛选项可能有两项,可能有三项,所以在初始化视图界面的时候,先初始化一个基础视图 baseView,并提供一组默认数据源。

当检测到有设置 delegate 和 datasource 的时候,再根据新的数据源重新绘制视图。

弹出菜单时背景变暗的处理方法

暂时没找到其他方法,所以只有粗暴的在 superview 添加一个灰色半透明的 shadowView 上去以达到背景变暗的效果。

什么时候才能够获取到 superview

在做菜单弹出的时候背景变暗的特性时,是需要用到 YXMenuView 的 superview 的,

在 superview 上创建一个隐藏的 View 设置灰色和适当透明再隐藏。

菜单弹出时显示,收回时再隐藏。

要从 YXMenuView 的实例获取到 superview 需要等到自身被加载 addSubview(self) 之后才能获取到 superview

一开始是想覆写属性的 didSet 来检测 superview,比如:

var superview: UIView! {
	didSet {
		// do something...
	}
}

实际上有提供一个检测自身被加到父视图当中的函数 didMoveToSuperview

override public func didMoveToSuperview() {
        // do something..
    }

当检测到被添加到 superview 之后就可以在 superview 创建 shadowView 了

Delegate 和 DataSource 的设计

这两个委托是参照 UITableViewDelegate 和 UItableViewDatasource 来设计的,基本使用方法相同

在进行筛选操作的时候,被选中的筛选项只有一个,所以就做了一个单项选择的class用来保存检测当前状态,定义了几种操作情况

Framework & Xib & Assets.xcassets

如果你自己写的 Framewrok 里面包含 xib 文件,在 loadNib 的过程中,需要这样来加载 bundle

let bundle = NSBundle(identifier: "com.xxx.YourProject")

这里的 identifier 填写你项目的 Bundle Identifier

而如果你的 Framework 里面包含 xcassets 素材文件,那么在其他项目使用这个 Framework 的时候必须要添加到 Embedded Binaries 里面,不然会报错找不到 image


  1. https://github.com/ShinCurry/YXMenuView ↩︎