我有一个UIViewController只有一个UIView,从底部覆盖了viewController的1/3.像这样
我想在另一个ViewController上呈现这个viewController.它应该从底部动画出现,它应该忽略到底部动画.
但我不希望它覆盖整个屏幕.显示它的viewController应该在后面可见.
这似乎是一个基本问题但我无法完成它.有人可以指点我的方向吗?
编辑:
这就是我迄今为止所尝试过的.我创建了这些类
// MARK: - class MyFadeInFadeOutTransitioning: NSObject,UIViewControllerTransitioningDelegate { var backgroundColorAlpha: CGFloat = 0.5 var shoulDismiss = false func animationController(forPresented presented: UIViewController,presenting: UIViewController,source: UIViewController) -> UIViewControllerAnimatedTransitioning? { let fadeInPresentAnimationController = MyFadeInPresentAnimationController() fadeInPresentAnimationController.backgroundColorAlpha = backgroundColorAlpha return fadeInPresentAnimationController } func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { let fadeOutDismissAnimationController = MyFadeOutDismissAnimationController() return fadeOutDismissAnimationController } } // MARK: - class MYFadeInPresentAnimationController: NSObject,UIViewControllerAnimatedTransitioning { let kPresentationDuration = 0.5 var backgroundColorAlpha: CGFloat? func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return kPresentationDuration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)! toViewController.view.backgroundColor = UIColor.clear let toViewFrame = transitionContext.finalFrame(for: toViewController) let containerView = transitionContext.containerView if let pickerContainerView = toViewController.view.viewWithTag(kContainerViewTag) { let transform = CGAffineTransform(translationX: 0.0,y: pickerContainerView.frame.size.height) pickerContainerView.transform = transform } toViewController.view.frame = toViewFrame containerView.addSubview(toViewController.view) UIView.animate(withDuration: 0.3,delay: 0.0,options: .curveLinear,animations: { toViewController.view.backgroundColor = UIColor(white: 0.0,alpha: self.backgroundColorAlpha!) if let pickerContainerView = toViewController.view.viewWithTag(kContainerViewTag) { pickerContainerView.transform = CGAffineTransform.identity } }) { (finished) in transitionContext.completeTransition(true) } } } // MARK: - class MYFadeOutDismissAnimationController: NSObject,UIViewControllerAnimatedTransitioning { let kDismissalDuration = 0.15 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return kDismissalDuration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let fromViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)! let toViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)! let containerView = transitionContext.containerView containerView.addSubview(toViewController.view) containerView.sendSubview(toBack: toViewController.view) UIView.animate(withDuration: kDismissalDuration,animations: { // fromViewController.view.backgroundColor = UIColor.clearColor() // if let pickerContainerView = toViewController.view.viewWithTag(kContainerViewTag) { // let transform = CGAffineTransformMakeTranslation(0.0,pickerContainerView.frame.size.height) // pickerContainerView.transform = transform // } fromViewController.view.alpha = 0.0 }) { (finished) in let canceled: Bool = transitionContext.transitionWasCancelled transitionContext.completeTransition(true) if !canceled { UIApplication.shared.keyWindow?.addSubview(toViewController.view) } } } }
在正在呈现的viewController中,我正在做如下
var customTransitioningDelegate: MYFadeInFadeOutTransitioning? = MYFadeInFadeOutTransitioning() init() { super.init(nibName: "SomeNibName",bundle: Bundle.main) transitioningDelegate = customTransitioningDelegate modalPresentationStyle = .custom customTransitioningDelegate?.backgroundColorAlpha = 0.0 }
它确实呈现了viewController,我也可以看到背景viewController.但我希望它能从底部呈现动画效果.用动画解雇底部.我怎样才能做到这一点 ?
解决方法
如果你想在半个屏幕上呈现一个视图控制器,我建议使用UIPresentationController类,它允许你在显示时设置视图控制器的框架.一个建议,这个方法将停止presentViewController的用户交互,直到你解雇presentViewController,所以如果你想在屏幕的一半显示视图控制器同时保持用户与presentsViewController的交互,你应该像其他答案一样使用容器视图建议.
这是UIPresentationController类的一个例子,可以执行您想要的操作
这是UIPresentationController类的一个例子,可以执行您想要的操作
import UIKit class ForgotPassWordPresentationController: UIPresentationController{ let blurEffectView: UIVisualEffectView! var tapGestureRecognizer: UITapGestureRecognizer = UITapGestureRecognizer() func dismiss(){ self.presentedViewController.dismiss(animated: true,completion: nil) } override init(presentedViewController: UIViewController,presenting presentingViewController: UIViewController?) { let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark) blurEffectView = UIVisualEffectView(effect: blurEffect) super.init(presentedViewController: presentedViewController,presenting: presentingViewController) tapGestureRecognizer = UITapGestureRecognizer(target: self,action: #selector(self.dismiss)) blurEffectView.autoresizingMask = [.flexibleWidth,.flexibleHeight] self.blurEffectView.isUserInteractionEnabled = true self.blurEffectView.addGestureRecognizer(tapGestureRecognizer) } override var frameOfPresentedViewInContainerView: CGRect{ return CGRect(origin: CGPoint(x: 0,y: self.containerView!.frame.height/2),size: CGSize(width: self.containerView!.frame.width,height: self.containerView!.frame.height/2)) } override func dismissalTransitionWillBegin() { self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in self.blurEffectView.alpha = 0 },completion: { (UIViewControllerTransitionCoordinatorContext) in self.blurEffectView.removeFromSuperview() }) } override func presentationTransitionWillBegin() { self.blurEffectView.alpha = 0 self.containerView?.addSubview(blurEffectView) self.presentedViewController.transitionCoordinator?.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) in self.blurEffectView.alpha = 1 },completion: { (UIViewControllerTransitionCoordinatorContext) in }) } override func containerViewWillLayoutSubviews() { super.containerViewWillLayoutSubviews() presentedView!.layer.masksToBounds = true presentedView!.layer.cornerRadius = 10 } override func containerViewDidLayoutSubviews() { super.containerViewDidLayoutSubviews() self.presentedView?.frame = frameOfPresentedViewInContainerView blurEffectView.frame = containerView!.bounds } }
当您在presentViewController框架外部点击时,这还会添加模糊视图和点按以关闭.您需要设置presentViewController的transitioningDelegate并实现
presentationController(forPresented呈现:UIViewController,呈现:UIViewController?,source:UIViewController) – > UIPresentationController?
在那里的方法.别忘了也设置
modalPresentationStyle = .custom
presentViewController的内容