ios - 查看其他 ViewController 后,用户输入数据不会保留
问题描述
用户输入输入到 ViewController1 上的 TextFields 和 TextViews 中,但是当我选择一个按钮以通过 segue 显示 ViewController2 或 ViewController3 时,在我返回 ViewController1(也通过另一个 segue)时,输入不再存在,好像该应用程序刚刚重新打开。当用户切换到不同的视图时,如何让初始用户输入保留在文本字段和文本视图中,直到用户点击 ViewController1 上的“发送电子邮件”按钮?
下面是我的代码
视图控制器1
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var DateTextField: UITextField!
@IBOutlet weak var ScrollView: UIScrollView!
@IBOutlet weak var FirstTextView: UITextField!
@IBOutlet weak var FirstName: UITextField!
@IBOutlet weak var OtherDetailsField: UITextView!
lazy var datePicker: UIDatePicker = {
let picker = UIDatePicker()
picker.datePickerMode = .date
picker.addTarget(self, action: #selector(datePickerChanged(_:)), for: .valueChanged)
return picker
}()
lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .none
return formatter
}()
// Adjust Scroll for Keyboard ------------------
@objc func adjustForKeyboard(notification: Notification) {
guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardScreenEndFrame = keyboardValue.cgRectValue
let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)
if notification.name == UIResponder.keyboardWillHideNotification {
ScrollView.contentInset = .zero
} else {
ScrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
}
ScrollView.scrollIndicatorInsets = ScrollView.contentInset
// let selectedRange = OtherDetailsField.selectedRange
// OtherDetailsField.scrollRangeToVisible(selectedRange)
}
override func viewDidLoad(){
super.viewDidLoad()
// Adjust Scroll for Keyboard ---------------
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
// Date Picker ---------------
DateTextField.inputView = datePicker}
@objc func datePickerChanged(_ sender: UIDatePicker){
DateTextField.text = dateFormatter.string(from: sender.date)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){view.endEditing(true)
}
// Dismiss Keyboard ------------------
func setupKeyboardDismissRecognizer(){
let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(
target: self, action: #selector(ViewController.dismissKeyboard))
tapRecognizer.cancelsTouchesInView = false
self.view.addGestureRecognizer(tapRecognizer)
}
@objc func dismissKeyboard() {
view.endEditing(true)
}
}
// Add Done Button to keypad toolbar -----------------
extension UITextField{
@IBInspectable var doneAccessory: Bool{
get{
return self.doneAccessory
}
set (hasDone) {
if hasDone{
addDoneButtonOnKeyboard()
}
}
}
func addDoneButtonOnKeyboard() {
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))
let items = [flexSpace, done]
doneToolbar.items = items
doneToolbar.sizeToFit()
self.inputAccessoryView = doneToolbar
}
@objc func doneButtonAction()
{
self.resignFirstResponder()
}
}
extension UITextView{
@IBInspectable var doneAccessory: Bool{
get{
return self.doneAccessory
}
set (hasDone) {
if hasDone{
addDoneButtonOnKeyboard()
}
}
}
func addDoneButtonOnKeyboard() {
let doneToolbar: UIToolbar = UIToolbar(frame: CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 50))
doneToolbar.barStyle = .default
let flexSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let done: UIBarButtonItem = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(self.doneButtonAction))
let items = [flexSpace, done]
doneToolbar.items = items
doneToolbar.sizeToFit()
self.inputAccessoryView = doneToolbar
}
@objc func doneButtonAction() {
self.resignFirstResponder()
}
}
视图控制器2
import UIKit
class ViewController2: UIViewController {
@IBOutlet weak var ScrollView: UIScrollView!
// Adjust Scroll for Keyboard ------------------
@objc func adjustForKeyboard(notification: Notification) {
guard let keyboardValue = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
let keyboardScreenEndFrame = keyboardValue.cgRectValue
let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)
if notification.name == UIResponder.keyboardWillHideNotification {
ScrollView.contentInset = .zero
} else {
ScrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height - view.safeAreaInsets.bottom, right: 0)
}
ScrollView.scrollIndicatorInsets = ScrollView.contentInset
//let selectedRange = yourTextView.selectedRange
//yourTextView.scrollRangeToVisible(selectedRange)
}
override func viewDidLoad() {
super.viewDidLoad()
// Adjust Scroll for Keyboard ---------------
let notificationCenter = NotificationCenter.default
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillHideNotification, object: nil)
notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
}
// Dismiss Keyboard ------------------
func setupKeyboardDismissRecognizer(){
let tapRecognizer: UITapGestureRecognizer = UITapGestureRecognizer(
target: self, action: #selector(ViewController.dismissKeyboard))
tapRecognizer.cancelsTouchesInView = false
self.view.addGestureRecognizer(tapRecognizer)
}
func dismissKeyboard()
{
view.endEditing(true)
}
}
视图控制器3
import UIKit
class ViewController3: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
}
解决方案
简短回答:您使用创建新实例的反向搜索,您可以使用“解雇”方法或使用标签栏控制器。
长答案:
最简单的解决方案是删除向后指向的segues,而是将'dismiss'方法放在'BACK'按钮代码块中:
self.dismiss(animated: true, completion: nil)
每次使用“dismiss”方法时,都会关闭实际的 ViewController 并返回上一个。
如果您希望“HOME”按钮之类的东西从任何 ViewController 回到第一个(根),您可以使用以下代码:
self.view.window!.rootViewController?.dismiss(animated: true,completion: nil)
但请记住 - 如果您在关闭之前不编写一些代码来保存您的数据,当您关闭它们时,您仍然会丢失 ViewController2 和 ViewController3 数据。
最后,如果您需要在用户在 ViewController 之间切换时显示您的数据,我会使用Tab bar controller。您可以在创建 Xcode 项目时使用模板“Tabbed App”创建它。
希望这可以帮助!不要把它当作 100%,我仍然是一个 Swift Rookie :)
推荐阅读
- sql - MSSQL 从 12 列中获取前 4 个值
- php - 如何使用 symfony 日期类型放置或发布日期值
- node.js - 从具有节点和角度 5 的 linux 服务器下载 zip 文件时,zip 文件成功下载但为空
- python - 在特定文件列的每一行上应用 for 循环
- plsql - ORACLE 中 deqeueu 和 enqueue 的 PL/SQL
- android - 如何从 Google play 获取应用程序列表
- animation - 如何在 Flutter 中跳过 NimaActor 动画的第一个 15 毫秒
- ruby - 在 Active Admin 中应用基于角色的访问授权的最佳方法是什么?
- spring-data - 如何调整 Spring Data JDBC 的 NamingStrategy
- javascript - 如何在javascript中获取动态子字符串?