更改模态视图控制器的大小

时间:2019-02-17 21:31:41

标签: ios swift uiviewcontroller modalviewcontroller

一旦用户点击一个按钮,我希望我的modalViewController在屏幕中间以小方块显示(您仍然可以在后台看到原始视图控制器)。

我发现的关于stackoverflow的几乎所有答案都使用情节提要来创建模态视图控制器,但是到目前为止,我已经找到了一切。

点击应调出模态视图的按钮时,此功能称为:

func didTapButton() {
    let modalViewController = ModalViewController()
    modalViewController.definesPresentationContext = true
    modalViewController.modalPresentationStyle = .overCurrentContext
    navigationController?.present(modalViewController, animated: true, completion: nil)
}

modalViewController包含:

import UIKit

class ModalViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .blue
        view.isOpaque = false

        self.preferredContentSize = CGSize(width: 100, height: 100)

    }

}

基于我发现的答案,我的印象是,如果我设置preferredContentSize = CGSize(width: 100, height: 100),那么它将使模式视图控制器变为100px x 100px。

但是,视图控制器占据了整个屏幕(标签栏除外,因为我设置了modalViewController.modalPresentationStyle = .overCurrentContext

我显然在这里错过了一步,但是我想以编程方式完成所有事情,因为我在项目中根本没有使用Storyboard(除了设置打开控制器)

预先感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您可以将视图控制器的背景色设置为清除,然后在视图控制器的中间创建一个视图,并将模式表示样式设置为.overCurrentContext,这样您将从后面看到该视图控制器。

这是编辑后的示例:

func didTapButton() {
    let modalViewController = storyboard?.instantiateViewController(withIdentifier: "ModalViewController") as! ModalViewController
    modalViewController.modalPresentationStyle = .overCurrentContext
    modalViewController.modalTransitionStyle = .crossDissolve // this will look more natural for this situation
    navigationController?.present(modalViewController, animated: true, completion: nil)
}

这是您显示的视图控制器类:

import UIKit

class ModalViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .clear
        createTheView()
    }

    private func createTheView() {

        let xCoord = self.view.bounds.width / 2 - 50
        let yCoord = self.view.bounds.height / 2 - 50

        let centeredView = UIView(frame: CGRect(x: xCoord, y: yCoord, width: 100, height: 100))
        centeredView.backgroundColor = .blue
        self.view.addSubview(centeredView)
    }
}

您已经可以从此处构建:为“较小”的视图控制器添加所需的外观:)

答案 1 :(得分:0)

modalPresentationStyle documentation告诉我们

  

在水平紧凑的环境中,模态视图控制器始终以全屏显示。

因此,如果要在iPhone的人像模式下执行此操作,则必须指定.custom演示文稿样式,并让过渡的委托人提供自定义演示文稿控制器。

我个人要让我的第二个视图控制器管理自己的演示文稿参数,所以我的第一个视图控制器可能只会:

class FirstViewController: UIViewController {
    @IBAction func didTapButton(_ sender: Any) {
        let controller = storyboard!.instantiateViewController(withIdentifier: "SecondViewController")
        present(controller, animated: true)
    }
}

然后我的第二个视图控制器将指定一个自定义过渡并指定一个自定义过渡委托:

class SecondViewController: UIViewController {
    private var customTransitioningDelegate = TransitioningDelegate()

    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()
    }
}

private extension SecondViewController {
    func configure() {
        modalPresentationStyle = .custom
        modalTransitionStyle = .crossDissolve.              // use whatever transition you want
        transitioningDelegate = customTransitioningDelegate
    }
}

然后,过渡的委托人将出售自定义表示控制器:

class TransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate {
    func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
        return PresentationController(presentedViewController: presented, presenting: presenting)
    }
}

该演示控制器将指定其大小:

class PresentationController: UIPresentationController {
    override var frameOfPresentedViewInContainerView: CGRect {
        let bounds = presentingViewController.view.bounds
        let size = CGSize(width: 200, height: 100)
        let origin = CGPoint(x: bounds.midX - size.width / 2, y: bounds.midY - size.height / 2)
        return CGRect(origin: origin, size: size)
    }

    override init(presentedViewController: UIViewController, presenting presentingViewController: UIViewController?) {
        super.init(presentedViewController: presentedViewController, presenting: presentingViewController)

        presentedView?.autoresizingMask = [
            .flexibleTopMargin,
            .flexibleBottomMargin,
            .flexibleLeftMargin,
            .flexibleRightMargin
        ]

        presentedView?.translatesAutoresizingMaskIntoConstraints = true
    }
}

这只是自定义过渡的冰山一角。您可以指定动画控制器(用于自定义动画),调暗/模糊背景等。有关自定义过渡的入门,请参阅WWDC 2013 Custom Transitions Using View Controllers视频,以及WWDC 2014视频View Controller Advancements in iOS 8和{{3} }深入研究表示控制器的细节。


例如,当您呈现模态视图时,您可能想使背景变暗和模糊。因此,您可以添加presentationTransitionWillBegindismissalTransitionWillBegin来为“变暗”视图的动画制作动画:

class PresentationController: UIPresentationController {
    ...

    let dimmingView: UIView = {
        let dimmingView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
        dimmingView.translatesAutoresizingMaskIntoConstraints = false
        return dimmingView
    }()

    override func presentationTransitionWillBegin() {
        super.presentationTransitionWillBegin()

        let superview = presentingViewController.view!
        superview.addSubview(dimmingView)
        NSLayoutConstraint.activate([
            dimmingView.leadingAnchor.constraint(equalTo: superview.leadingAnchor),
            dimmingView.trailingAnchor.constraint(equalTo: superview.trailingAnchor),
            dimmingView.bottomAnchor.constraint(equalTo: superview.bottomAnchor),
            dimmingView.topAnchor.constraint(equalTo: superview.topAnchor)
        ])

        dimmingView.alpha = 0
        presentingViewController.transitionCoordinator?.animate(alongsideTransition: { _ in
            self.dimmingView.alpha = 1
        }, completion: nil)
    }

    override func dismissalTransitionWillBegin() {
        super.dismissalTransitionWillBegin()

        presentingViewController.transitionCoordinator?.animate(alongsideTransition: { _ in
            self.dimmingView.alpha = 0
        }, completion: { _ in
            self.dimmingView.removeFromSuperview()
        })
    }
}

结果是:

A Look Inside Presentation Controllers