I will describe everything on an example with two ViewController. Comments in the code give the answer to your questions.
class ViewController1: UIViewController { override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white createPresentButton() } //создаем кнопку, с помощью которой будем переходить на новый VC func createPresentButton() { let button = UIButton(type: .system) button.setTitle("Present new VC", for: .normal) button.addTarget(self, action: #selector(presentButtonTapped), for: .touchUpInside) view.addSubview(button) //позиционирование button.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0), button.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0) ]) } @objc func presentButtonTapped() { let vc = ViewController2() //передача данных на новый VC vc.textFromFirstVC = "Test text" //переход на новый VC present(vc, animated: true, completion: nil) } } class ViewController2: UIViewController { //текст с первого VC var textFromFirstVC = "" override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .orange createCloseButton() createTestLabel() } //создаем кнопку, с помощью которой будем закрывать текущий VC func createCloseButton() { let button = UIButton(type: .system) button.setTitle("Close current VC", for: .normal) button.addTarget(self, action: #selector(closeButtonTapped), for: .touchUpInside) view.addSubview(button) //позиционирование button.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ button.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0), button.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 0) ]) } //label для отоборажения текста с первого VC func createTestLabel() { let label = UILabel(frame: CGRect(x: 0, y: 100, width: 300, height: 100)) label.text = textFromFirstVC view.addSubview(label) label.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ label.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0), label.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -100) ]) } //действие закрытия текущиего VC @objc func closeButtonTapped() { dismiss(animated: true, completion: nil) } }
Without a storyboard, we initialize the first ViewController in AppDelegate:
@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window!.makeKeyAndVisible() window!.rootViewController = ViewController1() return true } }
The result is: 

If you have any questions, ask.