I'm showing a View Controller as a Popup on a Parent ViewController(VC).
On Dismiss of ModalVC, data from ModalVC is passed to a function that reloads TableView in ParentVC with fresh data.
Things I've tried
- Calling 'reloadData' function before dismiss-statement from ModalVC
- Dismiss Completion handler
- Notification Center
- Singleton - To call reload-TableView function
- Dismiss Handler
Each time I get an error for this statement.
self.myTableView.reloadData()
FYI, 'myTableView' is an @IBOutlet with a valid connection
The Error Message:
Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
2019-11-30 02:40:30[31116:1071948] Fatal error: Unexpectedly found nil while implicitly
unwrapping an Optional value
I can confirm that I'm able to print data in the console that is being sent to Table Cell
I've also checked that on dismissing ModalVC, the ViewWillAppear/ViewDidAppear doesn't load and thanks to Sean for confirming it.
I need help reloading TableView in ParentVC on dismissing ModalVC/Popup.
ModalVC.swift
import UIKit
import ACFloatingTextfield_Swift
import Alamofire
import SwiftyJSON
class UISearchViewController: UIViewController,UITextViewDelegate,UITextFieldDelegate {
@IBOutlet weak var searhView: UIView!
@IBOutlet weak var patientUMRIpNo: ACFloatingTextfield!
@IBOutlet weak var fromDateTF: UITextField!
@IBOutlet weak var toDateTF: UITextField!
@IBOutlet weak var submitButtonOutlet: UIButton!
let logBookRef:LogbookViewController = LogbookViewController()
let datePickerView = UIDatePicker()
let datePicker = UIDatePicker()
let searchVC = "SearchPatient"
var rawSearchData : JSON!
var patientSearchDetails:[String:Any] = [:]
var patientNameArr:[String] = []
var patientAgeArr: [String] = []
var patientGenderArr:[String] = []
var patientUmrIdsArr:[String] = []
var patientMobileNoArr:[String] = []
var patientDatesArr:[String] = []
override func viewDidLoad() {
super.viewDidLoad()
submitButtonOutlet.layer.borderColor = #colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
submitButtonOutlet.layer.cornerRadius = 10
submitButtonOutlet.layer.masksToBounds = true
patientUMRIpNo.delegate = self
fromDateTF.delegate = self
toDateTF.delegate = self
searhView.layer.cornerRadius = 10
searhView.layer.masksToBounds = true
textFieldPlaceHolder()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard(_sender:)))
self.view.addGestureRecognizer(tapGesture)
}
@objc func dismissKeyboard(_sender:UITapGestureRecognizer){
patientUMRIpNo.resignFirstResponder()
fromDateTF.resignFirstResponder()
toDateTF.resignFirstResponder()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
if (touch!.view != self.searhView) {
self.dismiss(animated: true, completion: nil)
}
}
// TextField placeholder method
func textFieldPlaceHolder(){
placeHolderWhite(textFieldName: fromDateTF, placeHolderText: "Select from date")
placeHolderWhite(textFieldName: toDateTF, placeHolderText: "Select to date")
}
func placeHolderWhite(textFieldName:UITextField, placeHolderText:String){
textFieldName.attributedPlaceholder = NSAttributedString(string: placeHolderText ,attributes: [NSAttributedString.Key.foregroundColor: UIColor.white])
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
fromDateTF.inputView = datePickerView
toDateTF.inputView = datePicker
datePickerView.datePickerMode = .date
datePicker.datePickerMode = .date
let toolBar = UIToolbar().ToolbarPiker(mySelect: #selector(UISearchViewController.dismissPicker))
fromDateTF.inputAccessoryView = toolBar
toDateTF.inputAccessoryView = toolBar
datePickerView.addTarget(self, action: #selector(handleDatePicker(sender:)), for: .valueChanged)
datePicker.addTarget(self, action: #selector(handleDatePickerTwo(sender:)), for: .valueChanged)
return true
}
@objc func dismissPicker() {
view.endEditing(true)
}
@objc func handleDatePicker(sender: UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd-MM-yyyy"
fromDateTF.text = dateFormatter.string(from: sender.date)
}
@objc func handleDatePickerTwo(sender: UIDatePicker){
let formatDate = DateFormatter()
formatDate.dateFormat = "dd-MM-yyyy"
toDateTF.text = formatDate.string(from: sender.date)
}
func getPatientData(_ completion: @escaping (JSON?) -> Void){
let parameters:[String:Any] = [KeyConstants.mobileNo:self.getUserMobileNumberFromUserDefaults(),
KeyConstants.keyword:self.patientUMRIpNo.text ?? "" ,
KeyConstants.datedvalue:self.fromDateTF.text ?? "",
KeyConstants.todatedValue: self.toDateTF.text ?? ""]
print(parameters)
Alamofire.request(AppUrl.searchPatientUrl, method: .post, parameters: parameters).responseJSON { (response) in
if response.result.isSuccess{
let patientSearchJSON : JSON = JSON(response.result.value!)
// print(patientSearchJSON)
print("Raw Search Results......\(patientSearchJSON)")
if patientSearchJSON["status"] == "3"{
completion(patientSearchJSON)
//self.bindSearchedData(json: patientSearchJSON)
}
}
}}
func bindSearchedData(json:JSON){
for i in 0..<json["status_messsage"].count{
let patientNames = json["status_messsage"][i]["patient_name"].stringValue
let patientUmrNos = json["status_messsage"][i]["patient_umr_ipno"].stringValue
let patientGenderNames = json["status_messsage"][i]["patient_gender"].stringValue
let patientMobileNos = json["status_messsage"][i]["patient_mobile"].stringValue
let patientDateValues = json["status_messsage"][i]["patient_date"].stringValue
let patiendAgeValues = json["statue_message"][i]["patient_age"].stringValue
patientNameArr.append(patientNames)
patientUmrIdsArr.append(patientUmrNos)
patientGenderArr.append(patientGenderNames)
patientMobileNoArr.append(patientMobileNos)
patientDatesArr.append(patientDateValues)
patientAgeArr.append(patiendAgeValues)
}
}
@IBAction func submitButtonAction(_ sender: Any) {
showToast(message: "Submit func calling", font: UIFont.systemFont(ofSize: 15))
getPatientData() { value in
// Modal/Popup - DISMISS
self.dismiss(animated: true, completion: {
let logbookObj = LogbookViewController()
logbookObj.updatePatientSearch22(json: value!)
})
}
}
}
ParentVC.swift
import UIKit
import FSCalendar
import Alamofire
import SwiftyJSON
import ACFloatingTextfield_Swift
class LogbookViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, FSCalendarDataSource, FSCalendarDelegate,FSCalendarDelegateAppearance,LogbookCellDelegate{
@IBOutlet weak var calendar: FSCalendar!
@IBOutlet weak var headerTitle: UILabel!
@IBOutlet weak var calendarHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var logBookTableView: UITableView!
@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var logBookTableViewHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var overViewHeightConstraint: NSLayoutConstraint!
var patientUrl = [String]()
fileprivate var lunar: Bool = false {
didSet {
self.calendar.reloadData()
}
}
fileprivate let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "MMMM yyyy"
return formatter
}()
fileprivate lazy var dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
fileprivate let gregorian: NSCalendar! = NSCalendar(calendarIdentifier:NSCalendar.Identifier.gregorian)
fileprivate let gregorianmove:NSCalendar = NSCalendar(calendarIdentifier:NSCalendar.Identifier.gregorian)!
var datedValue = ""
var patientNamesList:[String] = []
var patientName = PatientSearchDataModel()
var patientAgeList: [String] = []
var patientAge = PatientSearchDataModel()
var patientGenderList:[String] = []
var patientGender = PatientSearchDataModel()
var patientUmrIdsList:[String] = []
var patientUmrId = PatientSearchDataModel()
var patientMobileNoList:[String] = []
var patientMobileNo = PatientSearchDataModel()
var patientCategoryDiagnosysList:[String] = []
var patientCategoryDiagnosys = PatientSearchDataModel()
var patientHospitalNameList:[String] = []
var hospitalName = PatientSearchDataModel()
var patientRefDoctorNameList:[String] = []
var patientRefDocName = PatientSearchDataModel()
var patientRefDoctorMobileNoList:[String] = []
var patientRefDocMobileNo = PatientSearchDataModel()
var patientOperationDoneList:[String] = []
var patientOperationDone = PatientSearchDataModel()
var patientDatesList:[String] = []
var patientDate = PatientSearchDataModel()
var dateValue = CalendarLogDataModel()
var dateValuesList:[String] = []
var logBookMonth = ""
var logBookYear = ""
//Declaring the variables for disply search options
var patientType:String?
var searchPatientIP:String?
var searchPatientFromDate:String?
var searchPatientToDate:String?
override func viewDidLoad() {
super.viewDidLoad()
self.calendar.appearance.headerMinimumDissolvedAlpha = 0.0
self.logBookTableView.isHidden = true
self.logBookTableView.separatorStyle = .none
self.logBookTableView.reloadData()
self.scrollView.bounces = false
if UIDevice.current.model.hasPrefix("iPad") {
self.calendarHeightConstraint.constant = 400
}
self.calendar.appearance.caseOptions = [.headerUsesUpperCase,.weekdayUsesUpperCase]
//self.calendar.select(self.formatter.date(from: "2017/08/10")!)
let scopeGesture = UIPanGestureRecognizer(target: self.calendar, action: #selector(self.calendar.handleScopeGesture(_:)))
self.calendar.addGestureRecognizer(scopeGesture)
// For UITest
self.calendar.accessibilityIdentifier = "calendar"
self.curentDate()
}
override func viewWillAppear(_ animated: Bool) {
callCalenderApi()
self.calendar.reloadData()
//calendar.appearance.eventColor = UIColor.greenColor
self.logBookTableView.reloadData()
}
override func viewDidAppear(_ animated: Bool) {
self.logBookTableView.reloadData()
}
@IBAction func rightArrowButton(_ sender: Any) {
calendar.setCurrentPage(getNextMonth(date: calendar.currentPage), animated: true)
}
@IBAction func leftArrowButton(_ sender: Any) {
calendar.setCurrentPage(getPreviousMonth(date: calendar.currentPage), animated: true)
}
func getNextMonth(date:Date)->Date {
self.logBookTableView.isHidden = true
return Calendar.current.date(byAdding: .month, value: 1, to:date)!
}
func getPreviousMonth(date:Date)->Date {
self.logBookTableView.isHidden = true
return Calendar.current.date(byAdding: .month, value: -1, to:date)!
}
@IBAction func backButton(_ sender: Any) {
let dashBoard = self.storyboard?.instantiateViewController(withIdentifier: "HomeVC") as? HomeViewController
self.navigationController?.pushViewController(dashBoard!, animated: true)
}
@IBAction func searchButton(_ sender: Any) {
let searchPatientVC = self.storyboard?.instantiateViewController(withIdentifier:"SearchVC") as? UISearchViewController
searchPatientVC!.modalTransitionStyle = .crossDissolve
searchPatientVC!.modalPresentationStyle = .overCurrentContext
self.present(searchPatientVC!, animated: true, completion: nil)
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return patientDatesList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = logBookTableView.dequeueReusableCell(withIdentifier: "LogbookTVC", for: indexPath) as? LogbookTableViewCell
cell?.delegate = self
cell?.selectionStyle = .none
cell?.patientNameLabel.text = patientNamesList[indexPath.row]
cell?.patientIpNumberLabel.text = patientUmrIdsList[indexPath.row]
cell?.patientGenderLabel.text = patientGenderList[indexPath.row]
cell?.patientMobileNumberLabel.text = patientMobileNoList[indexPath.row]
cell?.patientDateLabel.text = patientDatesList[indexPath.row]
cell?.shareButtOL.tag = indexPath.row
cell?.messageButtOL.tag = indexPath.row
cell?.deleteButtOL.tag = indexPath.row
cell?.printButtOL.tag = indexPath.row
cell?.viewButtOL.tag = indexPath.row
return cell!
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 200
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let cell = logBookTableView.dequeueReusableCell(withIdentifier: "LogbookTVC") as? LogbookTableViewCell
logBookTableViewHeightConstraint.constant = logBookTableView.contentSize.height
overViewHeightConstraint.constant = logBookTableView.contentSize.height + CGFloat(340)
cell?.contentView.backgroundColor = UIColor(red: 59, green: 87, blue: 157, alpha: 1.0)
}
func updatePatientSearch22(json: JSON){
self.patientNamesList = []
self.patientUmrIdsList = []
self.patientGenderList = []
self.patientMobileNoList = []
self.patientDatesList = []
self.patientAgeList = []
for i in 0..<json["status_messsage"].count{
let patientNamee = json["status_messsage"][i]["patient_name"].stringValue
let patientUmrNumber = json["status_messsage"][i]["patient_umr_ipno"].stringValue
let patientGenderName = json["status_messsage"][i]["patient_gender"].stringValue
let patientMobileNumber = json["status_messsage"][i]["patient_mobile"].stringValue
let patientDateValue = json["status_messsage"][i]["patient_date"].stringValue
let patiendAgeValue = json["statue_message"][i]["patient_age"].stringValue
self.patientName.patientname = patientNamee
self.patientUmrId.patientumripno = patientUmrNumber
self.patientGender.patientgender = patientGenderName
self.patientMobileNo.patientmobile = patientMobileNumber
self.patientDate.patientdate = patientDateValue
self.patientAge.patientage = patiendAgeValue
self.patientNamesList.append(patientNamee)
self.patientUmrIdsList.append(patientUmrNumber)
self.patientGenderList.append(patientGenderName)
self.patientMobileNoList.append(patientMobileNumber)
self.patientDatesList.append(patientDateValue)
self.patientAgeList.append(patiendAgeValue)
}
print("Patient Name List", self.patientNamesList)
print(self.patientUmrIdsList)
print(self.patientGenderList)
print(self.patientMobileNoList)
print(self.patientDatesList)
// ERROR-POINT
self.logBookTableView.reloadData()
}
}
}
self.myTableView.reloadData()
? – Mojtaba Hosseini