按照这个答案,我设法将半模态呈现添加ViewControllerB
到ViewControllerA
. 但是,在示例中,ViewControllerA
只是一个红色视图。我想将它连接到 IB 以便对其进行自定义。我尝试在类的 IB 中创建一个视图控制器ViewControllerB
并将其视图之一连接到,@IBOutlet var menuView: UIView!
而不是以menuView
编程方式创建(如示例中所示)。但是,在作为子视图nil
添加menuView
到视图时发现。任何帮助都会很棒。谢谢!
问问题
33 次
1 回答
0
几点观察:
在那个例子中,有一行说:
let vc = ViewControllerB()
您可以在 NIB 中定义此视图控制器的视图,这样可以正常工作。但是,如果您使用的是故事板,请将其替换为...
let vc = storyboard!.instantiateViewController(withIdentifier: “identifier")
...
identifier
您在 IB 的“身份检查器”中为该场景提供的作为“故事板 ID”的字符串在哪里。如果这是由按钮或类似的东西触发的,您也可以
gotoVCB
在该示例中删除它,然后像往常一样在 IB 中进行模态演示(例如control- 从按钮拖动到下一个场景)并选择“以模态方式呈现”。但是您必须确保配置了所有init
方法,例如:class ViewControllerB: UIViewController { // used if you use NIBs or just call `init()` override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) configure() } // used if you use storyboards required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) configure() } private func configure() { modalPresentationStyle = .custom transitioningDelegate = self } ... }
与直接问题无关,我可能建议将该答案的代码拆分为单独的对象,以防止视图控制器“膨胀”,更好地分离过渡委托对象、动画控制器等之间的职责。
例如,也许:
class ViewControllerB: UIViewController { let customTransitioningDelegate = PopUpMenuTransitioningDelegate() override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) configure() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) configure() } func configure() { modalPresentationStyle = .custom transitioningDelegate = customTransitioningDelegate } }
和
class PopUpMenuTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate { func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return PopUpMenuAnimationController(transitionType: .presenting) } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return PopUpMenuAnimationController(transitionType: .dismissing) } }
和
class PopUpMenuAnimationController: NSObject, UIViewControllerAnimatedTransitioning { enum TransitionType { case presenting case dismissing } let transitionType: TransitionType init(transitionType: TransitionType) { self.transitionType = transitionType super.init() } func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return 1 } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView guard let toVC = transitionContext.viewController(forKey: .to), let fromVC = transitionContext.viewController(forKey: .from) else { return } switch transitionType { case .presenting: containerView.addSubview(toVC.view) var rect = fromVC.view.bounds let menuHeight = fromVC.view.bounds.height / 2 rect.origin.y += fromVC.view.bounds.height rect.size.height = menuHeight toVC.view.frame = rect toVC.view.alpha = 0 UIView.animate(withDuration: 0.4, delay: 0, options: [.curveEaseOut], animations: { rect.origin.y = menuHeight toVC.view.frame = rect toVC.view.alpha = 1 }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) case .dismissing: UIView.animate(withDuration: 0.4, delay: 0, options: [.curveEaseOut], animations: { var rect = fromVC.view.frame rect.origin.y = toVC.view.bounds.height fromVC.view.frame = rect fromVC.view.alpha = 0 }, completion: { _ in transitionContext.completeTransition(!transitionContext.transitionWasCancelled) }) } } }
这将转换委托和动画控制器与视图控制器分离,并允许您在需要时将其与其他视图控制器一起使用。
请注意,我对 to 的参数也更加小心
completeTransition
。一旦开始使用交互式过渡,您可能会支持可取消的过渡。
于 2019-03-02T23:48:50.020 回答