在子vc上引用transitionCoordinator
时,它曾经在iOS7中的自定义容器类上调用transitionCoordinator
,但在iOS8中,情况并非如此。现在它返回零,我不知道应该改变什么来使这项工作。
我猜它是关于在iOS8中引入的UIPresentationController,但无法找到自定义容器视图控制器的正确实现。
答案 0 :(得分:0)
如马特在之前的SO question中所说:
因此,由于您甚至无法在特定情况下获得过渡协调员 您可以在其中为 内置的父视图控制器,很明显您获得的机会 一种在您尝试做自己的父视图的情况下 控制器为零
但是,根据transitionCoordinator,允许对其进行覆盖:
容器视图控制器可以覆盖此方法,但在大多数情况下 应该不需要。如果您确实要重写此方法,请先调用super 看看是否有合适的过渡协调员返回, 然后,如果有的话,将其退回。
因此,我将尝试为自己的VC容器创建自己的协调器。如果您使用UIViewPropertyAnimator
来操作VC容器的子级,则几乎是很简单的。
这里是一个例子:
class PropertyAnimatorTransitionCoordinator: NSObject, UIViewControllerTransitionCoordinator, UIViewControllerTransitionCoordinatorContext {
private let parentView: UIView
private let fromViewController: UIViewController?
private let toViewController: UIViewController
private let animator: UIViewPropertyAnimator
// MARK: - Life Cycle
init(parentView: UIView,
fromViewController: UIViewController?,
toViewController: UIViewController,
animator: UIViewPropertyAnimator) {
self.parentView = parentView
self.fromViewController = fromViewController
self.toViewController = toViewController
self.animator = animator
}
// MARK: - UIViewControllerTransitionCoordinator
func animate(alongsideTransition animation: ((UIViewControllerTransitionCoordinatorContext) -> Void)?,
completion: ((UIViewControllerTransitionCoordinatorContext) -> Void)? = nil) -> Bool {
var isSuccessful = false
if let animation = animation {
animator.addCompletion { [weak self] _ in
guard let context = self else { return }
animation(context)
}
isSuccessful = true
}
if let completion = completion {
animator.addCompletion { [weak self] _ in
guard let context = self else { return }
completion(context)
}
isSuccessful = true
}
return isSuccessful
}
func animateAlongsideTransition(in view: UIView?, animation: ((UIViewControllerTransitionCoordinatorContext) -> Void)?, completion: ((UIViewControllerTransitionCoordinatorContext) -> Void)? = nil) -> Bool {
return animate(alongsideTransition: animation, completion: completion)
}
func notifyWhenInteractionEnds(_ handler: @escaping (UIViewControllerTransitionCoordinatorContext) -> Void) {
animator.addCompletion { [weak self] _ in
guard let context = self else { return }
handler(context)
}
}
func notifyWhenInteractionChanges(_ handler: @escaping (UIViewControllerTransitionCoordinatorContext) -> Void) {
animator.addCompletion { [weak self] _ in
guard let context = self else { return }
handler(context)
}
}
// MARK: - UIViewControllerTransitionCoordinatorContext
var isAnimated: Bool {
return true
}
var presentationStyle: UIModalPresentationStyle {
return .none
}
var initiallyInteractive: Bool {
return false
}
var isInterruptible: Bool {
return animator.isInterruptible
}
var isInteractive: Bool {
return animator.isUserInteractionEnabled
}
var isCancelled: Bool {
return !animator.isRunning
}
var transitionDuration: TimeInterval {
return animator.duration
}
var percentComplete: CGFloat {
return animator.fractionComplete
}
var completionVelocity: CGFloat {
return 0
}
var completionCurve: UIView.AnimationCurve {
return animator.timingParameters?.cubicTimingParameters?.animationCurve ?? .linear
}
var targetTransform: CGAffineTransform {
return .identity
}
var containerView: UIView {
return parentView
}
func viewController(forKey key: UITransitionContextViewControllerKey) -> UIViewController? {
switch key {
case .from:
return fromViewController
case .to:
return toViewController
default:
return nil
}
}
func view(forKey key: UITransitionContextViewKey) -> UIView? {
switch key {
case .from:
return fromViewController?.view
case .to:
return toViewController.view
default:
return nil
}
}
}
在我的自定义容器中,我将像这样使用它:
class CustomContainerViewController: UIViewController {
private var customTransitionCoordinator: UIViewControllerTransitionCoordinator?
override var transitionCoordinator: UIViewControllerTransitionCoordinator? {
if let coordinator = super.transitionCoordinator {
return coordinator
}
return customTransitionCoordinator
}
override var shouldAutomaticallyForwardAppearanceMethods: Bool {
return false
}
func insertNewChild(_ viewController: UIViewController) {
let animator = UIViewPropertyAnimator(duration: 0.3, curve: .easeInOut)
customTransitionCoordinator = PropertyAnimatorTransitionCoordinator(
parentView: view,
fromViewController: nil,
toViewController: viewController,
animator: animator
)
animator.addCompletion { [weak self] _ in
guard let parent = self else { return }
viewController.didMove(toParent: parent)
self?.customTransitionCoordinator = nil
}
addChild(viewController)
viewController.beginAppearanceTransition(true, animated: true)
view.addSubview(viewController.view)
let target = view.bounds
viewController.view.frame = target
viewController.view.frame.origin.x = -target.width
view.layoutIfNeeded()
animator.addAnimations {
viewController.view.frame = target
}
animator.addCompletion { [weak self] _ in
guard let parent = self else { return }
viewController.endAppearanceTransition()
viewController.didMove(toParent: parent)
self?.customTransitionCoordinator = nil
}
animator.startAnimation()
}
}
当然,某些边缘情况没有处理。这是一个非常基本的例子。