Container
ContainerViewController
被设计为在多个子UIViewController
对象内嵌和切换的一种简单但灵活的方法。它是为了在没有导航栏的UINavigationController
,或者没有标签栏的UITabBarController
时填补空白而构建的。切换容器子子的唯一内置方式是通过其transition(to:)
API。
为了快速开始,您最简单的方法是从代码中创建ContainerViewController
并将其手动添加为父UIViewController
的子视图。这可以在该视图控制器的viewDidLoad
函数中轻松完成
private lazy var containerViewController: ContainerViewController = ContainerViewController(children: [.init(identifier: .a, viewController: controllerA),
.init(identifier: .b, viewController: controllerB)], delegate: self)
containerViewController.willMove(toParent: self)
addChild(containerViewController)
containerView.addSubview(containerViewController.view)
containerViewController.view.frame = containerView.bounds
containerViewController.didMove(toParent: self)
您会注意到在这个例子中,我们能够使用静态类型标识符.a
和.b
。这是因为我们在ContainerViewController.Child.Identifier
上声明了一个扩展,只需简单
extension ContainerViewController.Child.Identifier {
static let a = ContainerViewController.Child.Identifier(rawValue: "A")
static let b = ContainerViewController.Child.Identifier(rawValue: "B")
}
虽然这是推荐的做法,但ContainerViewController.Child.Identifier
符合ExpressibleByStringLiteral
和RawRepresentable
协议,因此这些标识符可以从任何String
在运行时初始化。
一旦您正确初始化并使ContainerViewController
可见,它将默认自动切换到其第一个Child
。这个行为由shouldAutomaticallyTransitionOnLoad
控件,当设置为true
时,容器在视图加载时将选择其第一个Child
对象。如果这个值设置为false
,或者ContainerViewController
在加载时没有Child
对象,它将等待进一步的指令,然后在嵌入和显示一个Child
之前等待。
为了开始显示子视图控制器,有几个选择
// If `child` is not already part of `ContainerViewController`, it will be added before it is displayed
let child = ContainerViewController.Child(identifier: .new, viewController: someViewController)
containerViewController.transition(to: child) { finished in
print("finished transitioning: \(finished)")
}
// If you know the identifier of an existing `Child` that is part of the container, you can alternatively request it:
containerViewController.transitionToChild(for: .new) { finished in
print("finished transitioning: \(finished)")
}
容器还具有几个有助于自定义其行为的委托回调。其中之一是一个返回UIViewControllerAnimatedTransitioning
对象的函数,与用于模态、导航和标签切换动画中的那些对象相同。
func containerViewController(_ container: ContainerViewController, animationControllerForTransitionFrom source: Child, to destination: Child) -> UIViewControllerAnimatedTransitioning? {
if useCustomAnimator, let sourceIndex = container.index(ofChild: source.viewController), let destinationIndex = container.index(ofChild: destination.viewController) {
return WipeTransitionAnimator(withStartIndex: sourceIndex, endIndex: destinationIndex)
}
return nil
}
灵感
容器是ContainerViewController
的演变,它曾是UtiliKit的一部分。大部分情况下,两者是源代码兼容的,但如果您要从UtiliKit升级到Container,请查看我们的迁移指南。
示例
要运行示例项目,克隆此仓库并打开iOS Example/iOS Example.xcworkspace
。
要求
需要iOS 10.0,tvOS 10.0
安装
使用Swift包管理器将此库添加到您的项目中。在Xcode中,这很简单:文件 > Swift Packages > 添加包依赖...,完成安装。下面的表格中列出了针对旧项目的其他安装选项。
CocoaPods
如果您已经使用CocoaPods,只需在您的Podfile
中添加'Container',然后运行pod install
。
Carthage
如果您已经使用Carthage,只需将其添加到您的Cartfile
。
github "BottleRocketStudios/Container" ~> 0.1
然后运行carthage update
以构建框架,并将生成的Container
.framework拖入您的Xcode项目。
作者
许可证
容器适用于 Apache 2.0 许可证。有关更多信息,请参阅许可证文件。