iOS MVC项目问题:无法通过Controller修改View内容
iOS MVC口令验证项目问题排查
我正在开发首个iOS MVC项目,功能为验证口令短语并开放用户权限,已创建以下3个文件:
1. Model:校验口令短语正确性
负责校验输入的口令是否正确,返回结果用于更新UILabel文本
import Foundation class passwordCheck { public static let model = passwordCheck() func passwordChecking (_ word: String) -> String { if word == "leohl" { return "Hello" } else { return "Error" } } }
2. View:展示UI元素
包含显示状态的UILabel和触发验证的UIButton
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() } }
3. ViewController:处理交互逻辑
点击按钮唤起输入弹窗,本应更新View的背景色和UILabel文本
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") } }
问题描述
所有功能看似正常,但在Alert中输入口令短语后,View中的UILabel内容无任何变化,终端报错信息如下:
-[RTIInputSystemClient remoteTextInputSessionWithID:performInputOperation:] 执行输入操作需要有效的sessionID
问题原因及修复方案
核心问题
ViewController中创建了两个独立的View实例:
- 全局声明的
myView:仅初始化但从未添加到视图层级中 viewDidLayoutSubviews里创建的theView:被添加到界面上显示,但弹窗回调中修改的是myView的label,导致界面无更新
修改后的ViewController代码
import UIKit class ViewController: UIViewController { let myView = View() override func viewDidLoad() { super.viewDidLoad() // 在viewDidLoad中配置myView并添加到视图 myView.startButton.addTarget(self, action: #selector(alertCheck), for: .touchUpInside) view.addSubview(myView) } override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // 利用viewDidLayoutSubviews更新myView的frame以适配safeArea let safeArea = view.safeAreaLayoutGuide.layoutFrame myView.frame = safeArea } @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 // 修改界面上实际显示的myView的label self.myView.helloLabel.text = passwordCheck.model.passwordChecking(alert.textFields?.first?.text ?? "") // 可选:添加背景色修改逻辑 self.myView.backgroundColor = alert.textFields?.first?.text == "leohl" ? .green : .red })) alert.addTextField() self.present(alert, animated: true) print("Button working") } }
关键修改点
- 移除
viewDidLayoutSubviews中重复创建的theView实例,统一使用全局的myView - 在
viewDidLoad中为myView绑定按钮点击事件并添加到视图层级 - 在
viewDidLayoutSubviews中更新myView的frame以适配安全区域 - 弹窗回调中修改的是界面上实际显示的
myView的label,同时可添加背景色修改逻辑
内容的提问来源于stack exchange,提问作者neuraldag
相关产品推荐
相关产品推荐

