测试已测试 | ✗ |
语言语言 | SwiftSwift |
许可证 | MIT |
发布上次发布 | 2017年1月 |
SwiftSwift 版本 | 3.0 |
SPM支持 SPM | ✗ |
由 Teodor Patraș 维护。
SideMenuController
是一个使用 Swift 编写的自定义容器视图控制器,当触发时,会在中心面板显示主要内容,在侧面板显示次要内容(选项菜单、导航菜单等)。侧面板可以显示在左侧或右侧,下方或上方中心面板。
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
![]() | ![]() |
如果您不希望使用上面提到的任何依赖关系管理器,您可以将 Source
文件夹中的源代码手动集成到项目中。
您可以使用 SideMenuController
开始的三个简单步骤
首先,您应该 添加一个菜单按钮图像 并 指定侧面板的位置。可选地,您还可以自定义其他首选项。这可以通过两种方式实现:
继承 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 的类更改为您刚刚创建的定制子类。
在 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
默认不会添加一个,您需要在切换到新的中心视图控制器时手动添加。
SideMenuController
可以与 Storyboard 转场一起使用,或者您可以按编程方式切换到新的中心视图控制器。
SideMenuController
定义了两个自定义转场
SideContainmentSegue
- 转换到新的侧面控制器(触发embedSideController
)
CenterContainmentSegue
- 转换到新的中心控制器(触发embedCenterController
)
在 Storyboard 文件中,从 SideMenuController
场景添加两个转场,一个用于中心视图控制器,另一个用于侧菜单视图控制器。之后,您可以根据需要切换的场景数量添加更多的 CenterContainmentSeuges
。
请记得在属性检查器中设置每个转场的相关属性
SideContainmentSegue | CenterContainmentSegue |
---|---|
![]() | ![]() |
要将在 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)
您几乎准备好了。最后一步是了解如何转换到新的中心视图控制器。
重要提示: SideMenuController
定义了一个扩展 UIViewController
以使其通过计算属性 public var sideMenuController: SideMenuController?
更易于访问。从任何 UIViewController
实例中,您可以键入 self.sideMenuController
来访问 SideMenuController
。如果调用者是它的子视图控制器之一,则它会返回 SideMenuController
,否则返回 nil
。
从现在开始,每当用户在选择侧菜单控制器中的选项时,您都可以轻松执行转场,如下所示
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
实例即可。
SideMenuController
由Teodor Patraş开发,并以MIT许可证发布。有关详细信息,请参阅LICENSE
文件。标志图形由Logo Maker创建。
您可以通过我的Twitter账号关注我或给我留言。如果此项目有任何问题,您可以提交工单。合并请求也欢迎。