I am new to Swift and want to make a simple application
When the user opens the app, it gets to the FirstViewController
where there is 1 Login button, when the user clicks on this button, I present a SecondViewController
modally
On the SecondViewController
there are text fields and an "Auth button", I want that by clicking on the "Auth Button", the SecondViewController
closes and the FirstViewController
opens the ThirdViewController
How to do it right?
I do not use storyboard, if it's important
CodePudding user response:
You are "new to Swift" ... you may want to spend more time learning the basics before trying to "make a simple application".
The problem is that, at this point, you don't even know what to ask, or proper terminology.
For example, you say:
- "gets to the FirstViewController" ... what do you mean "gets to"?
- "click" instead of "tap"
- "the
SecondViewController
closes and theFirstViewController
opens theThirdViewController
" ... "close" and "open" are ambiguous terms
I don't mean to sound harsh, but would you try to write a novel before learning the alphabet?
However, here is a quick, very simple example...
We start with FirstViewController
as the root controller... button tap presents SecondViewController
and sets a closure... button tap in that controller calls the closure, at which point we pass the user entered strings and replace the root controller with ThirdViewController
:
class FirstViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemRed
// create a "Login" button
let btn = UIButton()
btn.backgroundColor = .darkGray
btn.setTitleColor(.white, for: .normal)
btn.setTitleColor(.lightGray, for: .highlighted)
btn.setTitle("Login", for: [])
btn.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(btn)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// center the button in the view
btn.centerXAnchor.constraint(equalTo: g.centerXAnchor),
btn.centerYAnchor.constraint(equalTo: g.centerYAnchor),
btn.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.75),
btn.heightAnchor.constraint(equalToConstant: 50.0),
])
// add touchUpInside action
btn.addTarget(self, action: #selector(loginBtnTapped(_:)), for: .touchUpInside)
}
@objc func loginBtnTapped(_ sender: Any?) -> Void {
let secondVC = SecondViewController()
// set the closure
secondVC.theClosure = { [weak self] str1, str2 in
guard let self = self else { return }
// closure was called from SecondVC,
// dismiss it and then show ThirdVC
self.dismiss(animated: true, completion: {
let thirdVC = ThirdViewController()
// set the strings
thirdVC.val1 = str1
thirdVC.val2 = str2
// replace First VC with Third VC
UIApplication.shared.windows.first?.rootViewController = thirdVC
UIApplication.shared.windows.first?.makeKeyAndVisible()
})
}
// present the second VC
self.present(secondVC, animated: true, completion: nil)
}
}
class SecondViewController: UIViewController {
var theClosure: ((String, String) -> ())?
let tf1 = UITextField()
let tf2 = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemGreen
// stack view to arrange two fields and a button
let stack = UIStackView()
stack.axis = .vertical
stack.spacing = 20
stack.translatesAutoresizingMaskIntoConstraints = false
// add text fields to stack view
[tf1, tf2].forEach { tf in
tf.borderStyle = .roundedRect
stack.addArrangedSubview(tf)
}
// create an "Auth" button
let btn = UIButton()
btn.backgroundColor = .darkGray
btn.setTitleColor(.white, for: .normal)
btn.setTitleColor(.lightGray, for: .highlighted)
btn.setTitle("Auth", for: [])
// add button to stack view
stack.addArrangedSubview(btn)
view.addSubview(stack)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain stack view centered horizontally, near top
stack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
stack.centerXAnchor.constraint(equalTo: g.centerXAnchor),
stack.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.75),
btn.heightAnchor.constraint(equalToConstant: 50.0),
])
// add touchUpInside action
btn.addTarget(self, action: #selector(authBtnTapped(_:)), for: .touchUpInside)
}
@objc func authBtnTapped(_ sender: Any?) -> Void {
// get the text from the two fields
var s1 = tf1.text ?? ""
var s2 = tf2.text ?? ""
if s1.isEmpty { s1 = "Field 1 Empty" }
if s2.isEmpty { s2 = "Field 2 Empty" }
// call the closure with the two strings
theClosure?(s1, s2)
}
}
class ThirdViewController: UIViewController {
var val1: String = ""
var val2: String = ""
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
// create a multi-line label
let label = UILabel()
label.backgroundColor = .cyan
label.numberOfLines = 0
label.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(label)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
// constrain the label centered in the view
label.centerXAnchor.constraint(equalTo: g.centerXAnchor),
label.centerYAnchor.constraint(equalTo: g.centerYAnchor),
label.widthAnchor.constraint(equalTo: g.widthAnchor, multiplier: 0.75),
])
// set label text
var s: String = "User-entered strings:"
s = "\n\n"
s = val1
s = "\n\n"
s = val2
label.text = s
}
}