Any view controller can be shown as dialog. Use the present() method of controller to display other controller in modal mode.

To show messages use alerts - small built-in dialogs.

You can specify preferred content size if presentation style is not .pageSheet.

func showFilterDialog() {
    let dlg = FilterViewController() 
    dlg.modalPresentationStyle = .formSheet
    dlg.preferredContentSize = .init(width: 500, height: 800)
    dlg.modalTransitionStyle = .crossDissolve
    // dlg.delegate = self   
    present(dlg, animated: true)

Briefly about some presentation styles:

  • .pageSheet - controller is displayed centered in the presentation view. The size of content depends from several factors such as the screen size, orientation and font size. (default iOS 13+)
  • .formSheet - same as .pageSheet, but allows to provide a custom content size.
  • .popover - content is displayed in a popover view. In this case you need to setup the popoverPresentationController property of presented controller, otherwise it will be shown as .formSheet . Useful for hints and menus.
  • .fullScreen
  • .overFullScreen same as .fullScreen, but the presenting view can be transparent.

Since iOS 13 user can dismiss dialog by swipe down gesture. To prevent this behouver set the isModalInPresentation property of dialog to true.

if #available(iOS 13.0, *) {
    isModalInPresentation = true

Use the dismiss() method of dialog to close it programmatically. Typically method is called from some handler (UIButton’s action or UITapGestureRecognizer) within dialog.

 private lazy var applyFilterButton: UIButton = {
    let bt = UIButton()
    bt.addTarget(nil, action: #selector(applyFilter), for: .touchUpInside)
    // ..
    return bt

@objc private func applyFilter() {
    // ...
    dismiss(animated: true)

The UIAdaptivePresentationControllerDelegate protocol allows you to controll a dismissing of dialog. (iOS13+)

popover example