当另一个视图位于顶部时,UIPresentationController会改变大小

时间:2018-03-23 11:15:00

标签: ios swift

我正在尝试使用UIPresentationController在屏幕底部进行弹出,所以我在这里关注了raywenderlich指南:https://www.raywenderlich.com/139277/uipresentationcontroller-tutorial-getting-started。我做了完全相同的事情,我只改变了框架的大小和y位置。弹出窗口包含打开共享表的按钮,但出于某种原因,当我打开表单时,单击"保存到文件","刮到文件"视图显示,当我点击取消时,我的弹出窗口全屏显示片刻然后更改为我的自定义大小。 我尝试调试应用程序,发现containerViewWillLayoutSubviews()没有被调用,直到"保存到文件"观点被驳回。任何人都知道如何解决这个问题。谢谢

这是我的代码:

主要:

final class MainViewController: UIViewController {
// MARK: - Properties
lazy var slideInTransitioningDelegate = SlideInPresentationManager()

// MARK: - View Life Cycle
override func viewDidLoad() {
  super.viewDidLoad()
    }

@IBAction func showPopup(_ sender: Any) {
  let controller = storyboard.instantiateViewController(withIdentifier:   NSStringFromClass(MyPopUpController.self))
  as! MyPopUpController
slideInTransitioningDelegate.direction = .bottom
slideInTransitioningDelegate.disableCompactHeight = true
controller.transitioningDelegate = slideInTransitioningDelegate
controller.modalPresentationStyle = .custom
}

mypopucontroller

final class MyPopUpController: UIViewController {


    @IBAction func share(_ sender: Any) {
        let activityController = UIActivityViewController(activityItems: ["message"], applicationActivities: nil)
        present(activityController, animated: true)
    }
    // MARK: - View Life Cycle
  override func viewDidLoad() {
    super.viewDidLoad()
}

在演示控制器中滑动:

final class SlideInPresentationController: UIPresentationController {

  // MARK: - Properties
  fileprivate var dimmingView: UIView!
  private var direction: PresentationDirection

  override var frameOfPresentedViewInContainerView: CGRect {
    var frame: CGRect = .zero
    frame.size = size(forChildContentContainer: presentedViewController, withParentContainerSize: containerView!.bounds.size)
    switch direction {
    case .right:
      frame.origin.x = containerView!.frame.width*(1.0/3.0)
    case .bottom:
      frame.origin.y = containerView!.frame.height*0.5
    default:
      frame.origin = .zero
    }
    return frame
  }

  // MARK: - Initializers
  init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?, direction: PresentationDirection) {
    self.direction = direction
    super.init(presentedViewController: presentedViewController, presenting: presentingViewController)
    setupDimmingView()
  }

  override func presentationTransitionWillBegin() {
    containerView?.insertSubview(dimmingView, at: 0)
    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|[dimmingView]|", options: [], metrics: nil, views: ["dimmingView": dimmingView]))
    NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|[dimmingView]|", options: [], metrics: nil, views: ["dimmingView": dimmingView]))

    guard let coordinator = presentedViewController.transitionCoordinator else {
      dimmingView.alpha = 1.0
      return
    }

    coordinator.animate(alongsideTransition: { _ in
      self.dimmingView.alpha = 1.0
    })
  }

  override func dismissalTransitionWillBegin() {
    guard let coordinator = presentedViewController.transitionCoordinator else {
      dimmingView.alpha = 0.0
      return
    }

    coordinator.animate(alongsideTransition: { _ in
      self.dimmingView.alpha = 0.0
    })
  }

  override func containerViewWillLayoutSubviews() {
    presentedView?.frame = frameOfPresentedViewInContainerView
  }

  override func size(forChildContentContainer container: UIContentContainer, withParentContainerSize parentSize: CGSize) -> CGSize {
    switch direction {
    case .left, .right:
      return CGSize(width: parentSize.width*(2.0/3.0), height: parentSize.height)
    case .bottom, .top:
      return CGSize(width: parentSize.width, height: parentSize.height*0.67)
    }
  }
}

// MARK: - Private
private extension SlideInPresentationController {

  func setupDimmingView() {
    dimmingView = UIView()
    dimmingView.translatesAutoresizingMaskIntoConstraints = false
    dimmingView.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
    dimmingView.alpha = 0.0

    let recognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(recognizer:)))
    dimmingView.addGestureRecognizer(recognizer)
  }

  dynamic func handleTap(recognizer: UITapGestureRecognizer) {
    presentingViewController.dismiss(animated: true)
  }
}

slidein manager:

final class SlideInPresentationManager: NSObject {

  // MARK: - Properties
  var direction = PresentationDirection.left
  var disableCompactHeight = false
}

// MARK: - UIViewControllerTransitioningDelegate
extension SlideInPresentationManager:     UIViewControllerTransitioningDelegate {

  func presentationController(forPresented presented: UIViewController,     presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
let presentationController = SlideInPresentationController(presentedViewController: presented, presenting: presenting, direction: direction)
presentationController.delegate = self
return presentationController
  }

  func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return SlideInPresentationAnimator(direction: direction, isPresentation: true)
  }

  func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    return SlideInPresentationAnimator(direction: direction,     isPresentation: false)
  }
}

// MARK: - UIAdaptivePresentationControllerDelegate
extension SlideInPresentationManager:     UIAdaptivePresentationControllerDelegate {

  func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
if traitCollection.verticalSizeClass == .compact && disableCompactHeight {
  return .overFullScreen
} else {
  return .none
    }
  }

  func presentationController(_ controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
guard case(.overFullScreen) = style else { return nil }

return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "RotateViewController")
  }
}

slidein animator:

final class SlideInPresentationAnimator: NSObject {

  // MARK: - Properties
  let direction: PresentationDirection
  let isPresentation: Bool

  // MARK: - Initializers
  init(direction: PresentationDirection, isPresentation: Bool) {
    self.direction = direction
    self.isPresentation = isPresentation
    super.init()
  }
}

// MARK: - UIViewControllerAnimatedTransitioning
extension SlideInPresentationAnimator: UIViewControllerAnimatedTransitioning {

  func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
    return 0.3
  }

  func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
    let key = isPresentation ? UITransitionContextViewControllerKey.to : UITransitionContextViewControllerKey.from
    let controller = transitionContext.viewController(forKey: key)!

    if isPresentation {
      transitionContext.containerView.addSubview(controller.view)
    }

    let presentedFrame = transitionContext.finalFrame(for: controller)
    var dismissedFrame = presentedFrame
    switch direction {
    case .left:
      dismissedFrame.origin.x = -presentedFrame.width
    case .right:
      dismissedFrame.origin.x = transitionContext.containerView.frame.size.width
    case .top:
      dismissedFrame.origin.y = -presentedFrame.height
    case .bottom:
      dismissedFrame.origin.y = transitionContext.containerView.frame.size.height
    }

    let initialFrame = isPresentation ? dismissedFrame : presentedFrame
    let finalFrame = isPresentation ? presentedFrame : dismissedFrame

    let animationDuration = transitionDuration(using: transitionContext)
    controller.view.frame = initialFrame
    UIView.animate(withDuration: animationDuration, animations: {
      controller.view.frame = finalFrame
    }) { finished in
      transitionContext.completeTransition(finished)
    }
  }
}

1 个答案:

答案 0 :(得分:0)

您可以尝试继承UIPresentationController的子类并覆盖var presentedView: UIView?并强制执行presentedView的框架。

override var presentedView: UIView? {
    super.presentedView?.frame = frameOfPresentedViewInContainerView
    return super.presentedView
}

请参阅示例:Kyle Bashour https://kylebashour.com/posts/custom-view-controller-presentation-tips的“自定义视图控制器演示”