SideMenuController 0.2.4

SideMenuController 0.2.4

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布上次发布2017年1月
SwiftSwift 版本3.0
SPM支持 SPM

Teodor Patraș 维护。



SideMenuController

描述

SideMenuController 是一个使用 Swift 编写的自定义容器视图控制器,当触发时,会在中心面板显示主要内容,在侧面板显示次要内容(选项菜单、导航菜单等)。侧面板可以显示在左侧或右侧,下方或上方中心面板。

SideMenuController SideMenuController
SideMenuController SideMenuController

内容

  1. 功能
  2. 安装
  3. 支持的操作系统和 SDK 版本
  4. 使用方法
  5. 缓存
  6. 自定义
  7. 实现自定义转换
  8. 公开接口
  9. 代表
  10. 许可证
  11. 联系

功能

  • [x] 易用,完全可定制
  • [x] 左侧和右侧定位
  • [x] 覆盖和下方定位中心
  • [x] 自动方向更改调整。
  • [x] 完全可定制的转换动画
  • [x] 自定义状态栏 行为(详情见自定义
SideMenuController SideMenuController
SideMenuController SideMenuController

安装

手动

如果您不希望使用上面提到的任何依赖关系管理器,您可以将 Source 文件夹中的源代码手动集成到项目中。

支持的操作系统和 SDK 版本

  • 支持的构建目标 - iOS 8.0+(Xcode 7+)

使用

您可以使用 SideMenuController 开始的三个简单步骤

第一步

首先,您应该 添加一个菜单按钮图像指定侧面板的位置。可选地,您还可以自定义其他首选项。这可以通过两种方式实现:

1) 如果 SideMenuController 子类是您主Storyboard中的初始视图控制器

继承 SideMenuController 类并重写 init(coder:) 方法,您可以根据自己的风格更改首选项

class CustomSideMenuController: SideMenuController {

    required init?(coder aDecoder: NSCoder) {
        SideMenuController.preferences.drawing.menuButtonImage = UIImage(named: "menu")
        SideMenuController.preferences.drawing.sidePanelPosition = .overCenterPanelLeft
        SideMenuController.preferences.drawing.sidePanelWidth = 300
        SideMenuController.preferences.drawing.centerPanelShadow = true
        SideMenuController.preferences.animating.statusBarBehaviour = .showUnderlay
        super.init(coder: aDecoder)
    }
}

接下来,进入 Storyboard,将 SideMenuController 的类更改为您刚刚创建的定制子类。

2) 在所有其他情况下

AppDelegate.swift 中,重写 application:didFinishLaunchingWithOptions:

func func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    SideMenuController.preferences.drawing.menuButtonImage = UIImage(named: "menu")
    SideMenuController.preferences.drawing.sidePanelPosition = .overCenterPanelLeft
    SideMenuController.preferences.drawing.sidePanelWidth = 300
    SideMenuController.preferences.drawing.centerPanelShadow = true
    SideMenuController.preferences.animating.statusBarBehaviour = .showUnderlay
}

⚠️如果您没有指定菜单按钮的图像,SideMenuController 默认不会添加一个,您需要在切换到新的中心视图控制器时手动添加。

步骤 2

SideMenuController 可以与 Storyboard 转场一起使用,或者您可以按编程方式切换到新的中心视图控制器。

使用 Storyboard 转场

SideMenuController 定义了两个自定义转场

  • SideContainmentSegue - 转换到新的侧面控制器(触发 embedSideController
  • CenterContainmentSegue - 转换到新的中心控制器(触发 embedCenterController

在 Storyboard 文件中,从 SideMenuController 场景添加两个转场,一个用于中心视图控制器,另一个用于侧菜单视图控制器。之后,您可以根据需要切换的场景数量添加更多的 CenterContainmentSeuges

请记得在属性检查器中设置每个转场的相关属性

SideContainmentSegue CenterContainmentSegue
Example Example

要将在 SideMenuController 内嵌入初始视图控制器,您必须调用 performSegue(withIdentifier:sender:)。最快的方法是继承 SideMenuController 并重写 viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    performSegue(withIdentifier: "embedInitialCenterController", sender: nil)
    performSegue(withIdentifier: "embedSideController", sender: nil)
}

编程方式

您可以通过调用两个公共方法之一来按编程方式执行上述所有转换,而不使用转场:

public func embed(sideViewController: UIViewController)
public func embed(centerViewController: UViewController)

重要提示:如果您希望中心视图控制器与 UINavigationController 类型不同,您必须按编程方式将菜单按钮添加到其中之一或所有其子导航控制器。 SideMenuController 定义了一个扩展 UINavigationController 以便更容易做到这一点。只需调用 navigationController.addSideMenuButton() 即可。在调用此方法之前,请确保导航控制器已经嵌入到 SideMenuController 的子控制器层次结构中。

UITabBarController 的示例

// create the view controllers for center containment
let vc1 = UIViewController()
vc1.view.backgroundColor = UIColor.red
vc1.title = "first"
let nc1 = UINavigationController(rootViewController: vc1)
vc1.navigationItem.title = "first"

let vc2 = UIViewController()
vc2.view.backgroundColor = UIColor.yellow
vc2.title = "second"
let nc2 = UINavigationController(rootViewController: vc2)
vc2.navigationItem.title = "second"

let vc3 = UIViewController()
vc3.view.backgroundColor = UIColor.blue
vc3.title = "third"
let nc3 = UINavigationController(rootViewController: vc3)
vc3.navigationItem.title = "third"

let tabBarController = UITabBarController()
tabBarController.viewControllers = [nc1, nc2, nc3]

// create the side controller
let sideController = UITableViewController()

// embed the side and center controllers
sideMenuViewController.embed(sideViewController: sideController)
sideMenuViewController.embed(centerViewController: tabBarController)

// add the menu button to each view controller embedded in the tab bar controller
[nc1, nc2, nc3].forEach({ controller in
  controller.addSideMenuButton()
})

show(sideMenuViewController, sender: nil)

步骤 3

您几乎准备好了。最后一步是了解如何转换到新的中心视图控制器。

重要提示: SideMenuController 定义了一个扩展 UIViewController 以使其通过计算属性 public var sideMenuController: SideMenuController? 更易于访问。从任何 UIViewController 实例中,您可以键入 self.sideMenuController 来访问 SideMenuController。如果调用者是它的子视图控制器之一,则它会返回 SideMenuController,否则返回 nil

从现在开始,每当用户在选择侧菜单控制器中的选项时,您都可以轻松执行转场,如下所示

使用 Storyboard 转场

override func tableView(_ tableView: UITableView,
                            didSelectRowAt indexPath: IndexPath)  {
    sideMenuController?.performSegue(withIdentifier: segues[indexPath.row], sender: nil)
}

编程方式

override func tableView(_ tableView: UITableView,
                            didSelectRowAt indexPath: IndexPath)  {
    sideMenuController?.embed(centerViewController: someUIViewControllerInstance)
}

缓存

SideMenuController 提供了您能够缓存中心视图控制器而不是在更改时始终实例化新的视图控制器的可能性。

要将视图控制器切换到新的中心视图控制器并缓存其信息,请在 SideMenuController 上调用 embed(centerViewController:, cacheIdentifier:) 方法。

根据缓存标识符检索缓存的中心视图控制器,请在 SideMenuController 上调用 viewController(forCacheIdentifier:) 方法。

示例

在你的侧视图控制器(也称为菜单控制器)中

override func tableView(_ tableView: UITableView,
                            didSelectRowAt indexPath: IndexPath)  {

    // retrieve your identifier
    let cacheIdentifier = ...
    // retrieve your view controller
    let viewController = ...

    if let controller = sideMenuController?.viewController(forCacheIdentifier: cacheIdentifier) {
        sideMenuController?.embed(centerViewController: controller)
    } else {
        sideMenuController?.embed(centerViewController: UINavigationController(rootViewController: viewController), cacheIdentifier: cacheIdentifier)
    }
}

为了得到更详细的示例,请查看示例项目。

自定义

为了自定义 SideMenuController 的外观和行为,你可以操作 SideMenuController .Preferences 结构。它被分为三个子结构

  • 绘制 - 包含指定如何调整 SideMenuController 布局、屏幕定位的个性化属性。
  • 动画 - 包含指定不同组件使用何种动画的自定义属性。
  • 交互 - 包含指定用户如何与侧面板交互的自定义属性。
绘制 属性 描述
menuButtonImage 当设置此属性时,如果中心视图控制器是 UINavigationController 的子类,则 SideMenuController 将在导航栏的左侧或右侧添加一个按钮,以触发滑动动画。如果此属性不存在,或者中心视图控制器不是 UINavigationController 的子类,您必须自己将菜单按钮添加到所有将要嵌入的 UINavigationControllers 中。
sidePanelPosition 指定侧面板的位置。此属性可以取以下四个值之一: .underCenterPanelLeft.underCenterPanelRight.overCenterPanelLeft.overCenterPanelRight
sidePanelWidth 侧面板的宽度。
centerPanelOverlayColor 当侧面板为 .overCenterPanelLeft.overCenterPanelRight 时,当侧面板露出时,中心面板上方将显示一个覆盖层。传递此覆盖层的首选颜色。
centerPanelShadow 当侧面板为 .underCenterPanelRight.underCenterPanelLeft 时,您可以选择是否绘制中心面板的侧阴影。
动画 属性 描述
statusBarBehaviour 当侧面板露出时,状态栏的动画样式。这可以是:
+ .slideAnimation:将使用 UIStatusBarAnimation.slide 动画隐藏状态栏。
+ .fadeAnimation:将使用 UIStatusBarAnimation.fade 动画隐藏状态栏。
+ .horizontalPan:状态栏将随中心面板水平移动。
+ .showUnderlay:将显示与导航栏颜色相同的图层,在状态栏下方。
reavealDuration 揭露动画的持续时间。
hideDuration 隐藏动画的持续时间。
transitionAnimator TransitionAnimatable 子类,它定义了新中心视图控制器如何在屏幕上动画显示。
交互 属性 描述 讨论
panningEnabled 默认值是 true 当侧面板位于中心面板下方时,中心面板将识别平移。当侧面板位于中心面板上方时,将识别侧面板的平移。
swipingEnabled 默认值是 true 当侧面板置于中心面板下方时,不会实例化任何滑动手势识别器。当侧面板置于中心面板上方时,滑动将识别在中心面板上。
menuButtonAccessibilityIdentifier 要设置在菜单按钮上的可访问性标识符。

实现自定义过渡

为了为中心视图控制器实现自定义过渡动画,您需要创建一个符合TransitionAnimatable协议的struct,并实现: static func performTransition(forView view: UIView, completion: () -> Void)

示例

public struct FadeAnimator: TransitionAnimatable {

    public static func performTransition(forView view: UIView, completion: @escaping () -> Void) {
        CATransaction.begin()
        CATransaction.setCompletionBlock(completion)
        let fadeAnimation = CABasicAnimation(keyPath: "opacity")
        fadeAnimation.duration = 0.35
        fadeAnimation.fromValue = 0
        fadeAnimation.toValue = 1
        fadeAnimation.fillMode = kCAFillModeForwards
        fadeAnimation.isRemovedOnCompletion = true
        view.layer.add(fadeAnimation, forKey: "fade")
        CATransaction.commit()
    }
}

更多示例,请查看TransitionAnimator.swift

公共接口

公共方法

/**
 Toggles the side pannel visible or not.
*/
public func toggle()

/**
 Returns a view controller for the specified cache identifier

 - parameter identifier: cache identifier

 - returns: Cached UIViewController or nil
*/
public func viewController(forCacheIdentifier identifier: String) -> UIViewController?

/**
 Embeds a new side controller

 - parameter sideViewController: controller to be embedded
*/
public func embed(sideViewController controller: UIViewController)

/**
 Embeds a new center controller.

 - parameter centerViewController: controller to be embedded
 - parameter cacheIdentifier: identifier for the view controllers cache
*/
public func embed(centerViewController controller: UIViewController, cacheIdentifier: String? = nil)

公共属性

属性 类型 描述
首选项 SideMenuController.Preferences 用于自定义SideMenuController的首选项
sidePanelVisible Bool 用于检查侧面板是否可见
centerViewController UIViewController 用于获取当前嵌入的中心视图控制器
sideViewController UIViewController 用于获取当前嵌入的侧视图控制器
delegate SideMenuControllerDelegate 用于设置委托以通知特定事件

委托

SideMenuController定义了一个委托协议,您可以使用它来在侧面板显示或隐藏时接收通知

public protocol SideMenuControllerDelegate: class {
    func sideMenuControllerDidHide(_ sideMenuController: SideMenuController)
    func sideMenuControllerDidReveal(_ sideMenuController: SideMenuController)
}

为了接收上述回调,只需将委托属性赋给SideMenuController实例即可。

许可证

SideMenuControllerTeodor Patraş开发,并以MIT许可证发布。有关详细信息,请参阅LICENSE文件。标志图形由Logo Maker创建。

联系

您可以通过我的Twitter账号关注我或给我留言。如果此项目有任何问题,您可以提交工单。合并请求也欢迎。