Изменение размера контроллера модального вида - PullRequest
0 голосов
/ 18 февраля 2019

Как только пользователь нажимает кнопку, я хочу, чтобы мой 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

Я явно пропускаюшаг за шагом, но я хочу сделать все программно, так как я вообще не использую раскадровку в своем проекте (кроме настройки контроллера открытия)

Thanзаранее за вашу помощь !!

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Документация modalPresentationStyle сообщает нам

В горизонтально компактной среде контроллеры модального представления всегда представлены в полноэкранном режиме.

Итак, если вы хотите сделать это на 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 Настраиваемые переходы с использованием контроллеров представления Видео для начинающих по настраиваемым переходам и видеоролики WWDC 2014 ПросмотрУсовершенствования контроллеров в iOS 8 и Взгляд внутрь Контроллеры презентаций погружаются в детали контроллеров презентаций.


Например, вы можете захотеть затемнить и размыть фон, когдаВы представляете свой модальный вид.Таким образом, вы можете добавить presentationTransitionWillBegin и dismissalTransitionWillBegin для анимации представления этого вида «затемнения»:

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

, что дает:

enter image description here

0 голосов
/ 18 февраля 2019

Вы можете установить фоновый цвет контроллера представления, чтобы очистить, и затем создать представление в середине контроллера представления, и установить модальный стиль представления к .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)
    }
}

Вы уже можете построить здесь: добавьте желаемый вид для "меньший "просмотр контроллера:)

...