Документация 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()
})
}
}
, что дает: