Can't make changes in View from Controller

104 views Asked by At

I'm trying to create my first MVC project, which will check code phrase and open access to user. I've created 3 files:

  1. Model - checks if the code phrase is correct and returns a result that is used as the UILabel text.
import Foundation

class passwordCheck {
    public static let model = passwordCheck()
    
    func passwordChecking (_ word: String) -> String {
        if word == "leohl" {
            return "Hello"
        } else {
            return "Error"
        }
    }
}
  1. View - responsible for displaying the UI to the user. Contains UILabel for status and UIButton to start identification process.
import UIKit

class View: UIView {
    
    public let helloLabel: UILabel = {
        let label = UILabel()
        label.textAlignment = .center
        label.textColor = .black
        label.text = "Password?"
        label.font = .systemFont(ofSize: 20, weight: .bold)
        label.frame = CGRect(x: UIScreen.main.bounds.width/2-75, y: UIScreen.main.bounds.height/2-300, width: 150, height: 30)
        return label
    }()
    
    public let startButton: UIButton = {
        let button = UIButton()
        button.setTitle("Start", for: .normal)
        button.backgroundColor = .red
        button.frame = CGRect(x: UIScreen.main.bounds.width/2-50, y: UIScreen.main.bounds.height/2-50, width: 100, height: 50)
        button.layer.cornerRadius = 5
        button.setTitleColor(.orange, for: .highlighted)
        return button
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .white
        addSubview(helloLabel)
        addSubview(startButton)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
    }
}
  1. ViewController - call UIAlertController when UIButton is pressed. This changes the background colour of the view and the UILabel text.
import UIKit

class ViewController: UIViewController {
    let myView = View()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let safeArea = view.safeAreaLayoutGuide.layoutFrame
        let theView = View(frame: safeArea)
        theView.startButton.addTarget(self, action: #selector(alertCheck), for: .touchUpInside)
        view.addSubview(theView)
    }
    
    @objc func alertCheck() {
        callAlert(alertTitle: "Identify yourself", alertMessage: "Type the code phrase")
    }
    
    func callAlert(alertTitle: String, alertMessage: String) {
        let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Done", style: .default, handler: { action in
            self.myView.helloLabel.text = passwordCheck.model.passwordChecking(alert.textFields?.first?.text ?? "")
        }))
        alert.addTextField()
        self.present(alert, animated: true)
        print("Button working")
    }
}

So the problem is: everything seems to work, but when I enter the code phrase in the alert, nothing changes. Terminal says me:

-[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] perform input operation requires a valid sessionID

1

There are 1 answers

0
neuraldag On BEST ANSWER

I think the main problem is in my model itself, so I've changed it: combined View and ViewController files so I have only two: ViewController and Model.

ViewController:

import UIKit

class ViewController: UIViewController {
    let myView = View()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    }
    
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let safeArea = view.safeAreaLayoutGuide.layoutFrame
        let theView = View(frame: safeArea)
        theView.startButton.addTarget(self, action: #selector(alertCheck), for: .touchUpInside)
        view.addSubview(theView)
    }
    
    @objc func alertCheck() {
        callAlert(alertTitle: "Identify yourself", alertMessage: "Type the code phrase")
    }
    
    func callAlert(alertTitle: String, alertMessage: String) {
        let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: .alert)
        alert.addTextField()
        alert.addAction(UIAlertAction(title: "Done", style: .default, handler: { action in
            self.myView.helloLabel.text = passwordCheck.model.passwordChecking(alert.textFields?.first?.text ?? "")
        }))
        self.present(alert, animated: true)
        print("Button working")
    }
}

Model:

import Foundation

class Model {
    public static let model = Model()
    
    func passCheck (_ word: String) -> String {
        if word == "leohl" {
            return "Hello"
        } else {
            return "Error"
        }
    }
}

Now everything works as it should. But if you have any additions, I would love to hear them!