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
}
Container 是 ContainerViewController
的演变,该视图控制器曾是 UtiliKit 的一部分。 在大多数情况下,两者在源代码上是兼容的,但如果你要从 UtiliKit 升级到 Container,请查看我们的 迁移指南。
要运行示例项目,请克隆此仓库并打开 iOS Example/iOS Example.xcworkspace
。
需要 iOS 10.0、tvOS 10.0
使用 Swift Package Manager 将其添加到您的项目中。 在 Xcode 中,只需:File > Swift Packages > Add Package Dependency... 即可完成。 以下显示了传统项目的替代安装选项。
如果您已在使用 CocoaPods,只需将 'Container' 添加到您的 Podfile
,然后运行 pod install
。
如果您已在使用 Carthage,只需添加到您的 Cartfile
github "BottleRocketStudios/Container" ~> 0.1
然后运行 carthage update
以构建框架,并将构建的 Container
.framework 拖到您的 Xcode 项目中。
Container 在 Apache 2.0 许可证下可用。 有关更多信息,请参见 LICENSE 文件。
请参阅 CONTRIBUTING 文档。 谢谢您,贡献者!