更改模态视图控制器的大小 [英] Changing the size of a modal view controller

查看:58
本文介绍了更改模态视图控制器的大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我发现几乎所有关于 stackoverflow 的答案都使用故事板来创建模态视图控制器,但我已经找到了所有我发现的东西.

当你点击应该调出模态视图的按钮时,这个函数被调用:

func didTapButton() {让 modalViewController = ModalViewController()modalViewController.definesPresentationContext = truemodalViewController.modalPresentationStyle = .overCurrentContextnavigationController?.present(modalViewController, 动画: true, 完成: nil)}

modalViewController 包含:

导入 UIKit类 ModalViewController: UIViewController {覆盖 func viewDidLoad() {super.viewDidLoad()view.backgroundColor = .blueview.isOpaque = falseself.preferredContentSize = CGSize(width: 100, height: 100)}}

根据我找到的答案,我的印象是如果我设置 preferredContentSize = CGSize(width: 100, height: 100),那么它会使模态视图控制器为 100px x 100px.

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

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

预先感谢您的帮助!!

解决方案

modalPresentationStyle

Once, the user taps a button, I want my modalViewController to appear as a small square in the middle of the screen (where you can still see the original view controller in the background).

Almost every answer on stackoverflow I find uses the storyboard to create a modal view controller, but I've gotten this far with everything I've found.

When you tap the button that is supposed to bring up the modal view, this function is called:

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

And the modalViewController contains:

import UIKit

class ModalViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = .blue
        view.isOpaque = false

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

    }

}

Based on the answers I found, I was under the impression that if I set preferredContentSize = CGSize(width: 100, height: 100), then it would make the modal view controller 100px x 100px.

However, the view controller takes up the entire screen (except for the tab bar because I set modalViewController.modalPresentationStyle = .overCurrentContext

I'm obviously missing a step here, but I want to do everything programmatically as I'm not using the Storyboard at all in my project (except for setting the opening controller)

Thanks in advance for you help!!

解决方案

The modalPresentationStyle documentation tells us

In a horizontally compact environment, modal view controllers are always presented full-screen.

So, if you want to do this in a iPhone in portrait mode, you have to specify a .custom presentation style and have your transitioning delegate vend a custom presentation controller.

I’d personally let my second view controller manage its own presentation parameters, so my first view controller might only:

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

And then my second view controller would specify a custom transition and specify a custom transitioning delegate:

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

Then that transitioning delegate would vend the custom presentation controller:

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

And that presentation controller would specify its size:

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

This is just the tip of the iceberg with custom transitions. You can specify the animation controller (for custom animations), dim/blur the background, etc. See WWDC 2013 Custom Transitions Using View Controllers video for a primer on custom transitions, and WWDC 2014 videos View Controller Advancements in iOS 8 and A Look Inside Presentation Controllers dive into the details of presentation controllers.


For example, you might want to dim and blur the background when you present your modal view. So you might add presentationTransitionWillBegin and dismissalTransitionWillBegin to animate the presentation of this "dimming" view:

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

That yields:

这篇关于更改模态视图控制器的大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆