Tableview doesn't show data on ipad with iOS 9.3 version - swift

I am showing the data on tableview. Everything is working fine on iphone and ipad but data is not showing on ipad with version 9.3.
import UIKit
class AddPatientViewController: UIViewController, UITableViewDelegate,UITableViewDataSource,UITextViewDelegate,UITextFieldDelegate{
#IBOutlet weak var explain: UITextView!
#IBOutlet weak var name: UILabel!
#IBOutlet weak var tblViewAddPatient: UITableView!
#IBOutlet weak var mobile: ZWTextField!
#IBOutlet weak var age: ZWTextField!
#IBOutlet weak var fullname: ZWTextField!
#IBOutlet weak var btnFemale: UIButton!
#IBOutlet weak var btnMale: UIButton!
var gender :String = ""
var username :String = ""
var complain :String = ""
var strLabel = UILabel()
var indicator = UIActivityIndicatorView()
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
var arrComplain = ["-Check-Up","-Teeth Cleaning","-Peroidonatal","-Dental Fillings","-Prothesis","-Extraction","-Hollywoods Smile","-Childrens's Teeth","-Bleaching"]
var arrManaege = ["0","0","0","0","0","0","0","0","0"]
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
explain.delegate = self
let defaults1 = UserDefaults.standard
let user = defaults1.object(forKey: "user") as? NSData
let responseData = NSKeyedUnarchiver.unarchiveObject(with: user! as Data) as? ResponseModel
if responseData != nil {
if responseData?.profile != nil {
username = (responseData?.profile[0].userName)!;
name.text = responseData?.profile[0].userFullName
}
}
mobile.delegate = self
age.delegate = self
fullname.delegate = self
tblViewAddPatient.dataSource = self
tblViewAddPatient.delegate = self
let tapFirstGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard(_:)))
view.isUserInteractionEnabled = true
view.addGestureRecognizer(tapFirstGestureRecognizer)
// Do any additional setup after loading the view.
}
func dismissKeyboard(_ sender: UITapGestureRecognizer) {
view.endEditing(true)
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" // Recognizes enter key in keyboard
{
textView.resignFirstResponder()
return false
}
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
if textField == fullname {
age.becomeFirstResponder()
} else if textField == age {
mobile.becomeFirstResponder()
} else if textField == mobile {
mobile.resignFirstResponder()
}
return true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func backClick(_ sender: UIButton) {
_ = self.navigationController?.popViewController(animated: true)
}
#IBAction func btnFemaleClicked(_ sender: Any) {
if(btnFemale.isSelected){
}else{
btnFemale.isSelected = true
btnMale.isSelected = false
}
}
#IBAction func btnMaleClicked(_ sender: Any) {
if(btnMale.isSelected){
}else{
btnFemale.isSelected = false
btnMale.isSelected = true
}
}
// Tableview delegates and datasource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrComplain.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tblViewAddPatient.dequeueReusableCell(withIdentifier: "AddPatientTCC") as! AddPatientTCC
cell.selectionStyle = .none
cell.lblTitel.text = arrComplain[indexPath.row]
if (arrManaege[indexPath.row] == "0"){
cell.btnCheckBox.isSelected = false
}else{
cell.btnCheckBox.isSelected = true
}
cell.btnCheckBox.tag = indexPath.row
cell.btnCheckBox.addTarget(self, action: #selector(AddPatientViewController.btnCheckBoxClicked(_:)), for: .touchUpInside)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if (arrManaege[indexPath.row] == "0"){
arrManaege[indexPath.row] = "1"
}else{
arrManaege[indexPath.row] = "0"
}
tblViewAddPatient.reloadData()
}
#IBAction func saveClick(_ sender: UIButton) {
if fullname.text!.isEmpty {
showAlerError(titleText: "Error", messagetext: "All fields are Mandatory");
return
}
if age.text!.isEmpty {
showAlerError(titleText: "Error", messagetext: "All fields are Mandatory");
return
}
if mobile.text!.isEmpty {
showAlerError(titleText: "Error", messagetext: "All fields are Mandatory");
return
}
if explain.text!.isEmpty {
showAlerError(titleText: "Error", messagetext: "All fields are Mandatory");
return
}
if btnMale.isSelected == false , btnFemale.isSelected == false {
showAlerError(titleText: "Error", messagetext: "All fields are Mandatory");
return
}
if arrManaege[0] == "0",arrManaege[1] == "0",arrManaege[2] == "0",arrManaege[3] == "0",arrManaege[4] == "0",arrManaege[5] == "0",arrManaege[6] == "0",arrManaege[7] == "0",arrManaege[8] == "0" {
showAlerError(titleText: "Error", messagetext: "All fields are Mandatory");
return
}
if btnFemale.isSelected == true {
gender = "Female"
} else {
gender = "Male"
}
complain = arrManaege[0]+arrManaege[1]+arrManaege[2]+arrManaege[3]+arrManaege[4]+arrManaege[5]+arrManaege[6]+arrManaege[7]+arrManaege[8];
let netowrk = NetworkCall();
if Reachability.isConnectedToNetwork() == true {
self.showLoading(title: "Please wait")
netowrk.addPatient(patientMobile: mobile.text!,patientGender: gender,patientAge: age.text!,patientComplaint: complain,patientExplainComplain: explain.text!,paitentName: fullname.text!,username: username) { responseObject in
self.hideLoading()
if responseObject.status == "true" {
print("Success view controller");
self.showAlerError(titleText: "Success", messagetext: "Patient Added successfully");
} else {
self.showAlerError(titleText: "Error", messagetext: responseObject.message!);
}
return
}
} else {
self.showAlerError(titleText: "Error", messagetext: "Please check Internet connectivity");
}
}
func btnCheckBoxClicked(_ sender: UIButton) {
if (arrManaege[sender.tag] == "0"){
arrManaege[sender.tag] = "1"
}else{
arrManaege[sender.tag] = "0"
}
tblViewAddPatient.reloadData()
}
func textViewDidBeginEditing(_ textView: UITextView)
{
if textView.text == "Explain your compaint"
{
textView.text = ""
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text == ""
{
textView.text = "Explain your compaint"
}
}
func showLoading(title: String) {
strLabel.removeFromSuperview()
indicator.removeFromSuperview()
effectView.removeFromSuperview()
strLabel = UILabel(frame: CGRect(x: 50, y: 0, width: 160, height: 46))
strLabel.text = title
strLabel.font = UIFont.systemFont(ofSize: 14, weight: UIFontWeightMedium)
strLabel.textColor = UIColor(white: 0.9, alpha: 0.7)
effectView.frame = CGRect(x: view.frame.midX - strLabel.frame.width/2, y: view.frame.midY - strLabel.frame.height/2 , width: 160, height: 46)
effectView.layer.cornerRadius = 15
effectView.layer.masksToBounds = true
indicator = UIActivityIndicatorView(activityIndicatorStyle: .white)
indicator.frame = CGRect(x: 0, y: 0, width: 46, height: 46)
indicator.startAnimating()
effectView.addSubview(indicator)
effectView.addSubview(strLabel)
view.addSubview(effectView)
}
func hideLoading() {
self.effectView.removeFromSuperview()
//indicator.stopAnimating()
}
func showAlerError(titleText:String,messagetext:String) {
let alertController = UIAlertController(title: titleText, message:
messagetext, preferredStyle: UIAlertControllerStyle.alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))
self.present(alertController, animated: true, completion: nil)
}
}
I am using swift 3.1 but don't know why it is not showing data on iPad with iOS version 9.3 only. Please help me as I an new to swift. I tried all option but nothing is working for me.

Related

Swift: How can I solve the error: Thread 1: Fatal error: Index out of range

I want to eliminate an element of my array with an action swipe.
But at the time of sliding the app:
// Thread 1: Fatal error: Index out of range
This is how the error is presented:
enter image description here
This is added the element:
enter image description here
Main ViewController.
//
// ViewController.swift
// arregloUnidimensional
//
// Created by Leonardo Rubio on 10/06/22.
//
import UIKit
import Foundation
class ViewController: UIViewController {
//MARK: - Outlets
#IBOutlet weak var fieldNombre:UITextField!
#IBOutlet weak var fieldSueldo:UITextField!
#IBOutlet weak var butonRegistrar:UIButton!
#IBOutlet weak var tableView:UITableView!
#IBOutlet weak var labelPromedio:UILabel!
#IBOutlet weak var labelSueldosMayores:UILabel!
#IBOutlet weak var buttonFinish:UIButton!
//MARK: - Private
private var arrayDatos = [DataModel]()
private var counter:Int = 1
private var attempts:Int = 1
private var salaries = [Double]()
private var average:Double = Double()
private var higherSalaries = [Double]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.dataSource = self
self.tableView.delegate = self
self.tableView.register(UINib(nibName: "CustomCell", bundle: nil), forCellReuseIdentifier: "cell")
//Labells.
customizeLabel(anyLabel: self.labelPromedio)
customizeLabel(anyLabel: self.labelSueldosMayores)
//Buttons.
customizeButton(anyButton: self.butonRegistrar)
customizeButton(anyButton: self.buttonFinish)
}
//MARK: - Actions
#IBAction func accionRegistrar(_ sender:UIButton){
validacion()
self.labelPromedio.text = "Promedio: \(Double(calculateAverage()))"
}
#IBAction func finishAction(_ sender:UIButton){
if self.arrayDatos.count > 1{
if self.attempts <= 1{
self.labelSueldosMayores.text = "Sueldos: \(sueldosM())"
self.attempts += 1
self.fieldNombre.text = ""
self.fieldSueldo.text = ""
}
}else{
showAlert(titulo: "", mensaje: "No es posible promediar, ingresa mas datos.")
}
}
//MARK: - Methods
private func showAlert(titulo:String,mensaje:String){
let alert = UIAlertController(title: titulo, message: mensaje, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Aceptar", style: .default))
present(alert, animated: true)
}
private func isNumber(text:String)->Bool{
if Int(text) != nil{
return true
}else{
return false
}
}
private func validacion (){
if let nombre = self.fieldNombre.text{
if let sueldo = self.fieldSueldo.text{
if self.counter <= 3{
let isNumber = isNumber(text: sueldo)
if isNumber{
if nombre != ""{
let empleado = DataModel(nombre: nombre, sueldo: Int(sueldo))
self.salaries.append(Double(sueldo)!)
self.arrayDatos.append(empleado)
print(self.arrayDatos)
self.counter += 1
self.tableView.reloadData()
self.fieldNombre.text = ""
self.fieldSueldo.text = ""
}else{
showAlert(titulo: "", mensaje: "Ingresa un nombre.")
}
}else{
showAlert(titulo: "", mensaje: "Ingresa una cantidad valida. '\(sueldo)' no es una cantidad.")
}
}else{
showAlert(titulo: "Alto", mensaje: "El limite de elementos es: \(3)")
}
}
}else{
showAlert(titulo: "", mensaje: "Ingresa un nombre.")
}
}
private func calculateAverage() -> Double{
self.average = 0
var suma = 0.0
for cantidad in self.salaries{
suma += cantidad
}
self.average = suma / Double(self.salaries.count)
return self.average
}
private func sueldosM() -> [Double]{
for cantidad in self.salaries{
if cantidad > self.average{
self.higherSalaries.append(cantidad)
}
}
return self.higherSalaries
}
private func customizeLabel(anyLabel:UILabel){
anyLabel.layer.cornerRadius = anyLabel.frame.size.height/5.0
anyLabel.layer.masksToBounds = false
anyLabel.layer.borderColor = UIColor.systemGray6.cgColor
anyLabel.layer.borderWidth = 1.0
anyLabel.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
anyLabel.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
anyLabel.layer.shadowOpacity = 1.0
anyLabel.layer.shadowRadius = 5.0
}
private func customizeButton(anyButton:UIButton){
anyButton.layer.cornerRadius = anyButton.bounds.height / 5.0
anyButton.clipsToBounds = false
anyButton.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
anyButton.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
anyButton.layer.shadowOpacity = 1.0
anyButton.layer.shadowRadius = 0.0
}
}
//MARK: - UITableViewDataSource
extension ViewController:UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.arrayDatos.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CustomCell else{
return UITableViewCell()
}
if !self.arrayDatos.isEmpty{
let empleado = self.arrayDatos[indexPath.row]
cell.llenarEtiquetas(empleado: empleado,index: indexPath.row)
}
return cell
}
}
//MARK: - UITableViewDragDelegate
extension ViewController:UITableViewDelegate{
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let item = UIContextualAction(style: .destructive, title: "Eliminar") { (contextualAction, view, boolValue) in
self.arrayDatos.remove(at: indexPath.row)
}
let swipeActions = UISwipeActionsConfiguration(actions: [item])
return swipeActions
}
}
Any help is welcome.
Thanks
In extension ViewController, you could try replacing self.arrayDatos.remove(at: indexPath.row) with
if indexPath.row < self.arrayDatos.count && !(indexPath.row < 0) {
self.arrayDatos.remove(at: indexPath.row)
}
Do the same wherever you use self.arrayDatos and indexPath.row as an index.

App displays text with different characters swift

I am making a chat app. When i send my messages or receive from other user they end up being displayed like this. What might be the issue? It works alright but sometimes it just changes the way the texts are displayed. Am not sure what am missing in this. Can anyone take a look at it. Kindly. Thanks in advance
Below is my code
class ChatController: UIViewController,UITextViewDelegate,UITableViewDataSource,UITableViewDelegate,UIGestureRecognizerDelegate{
#IBOutlet weak var txtViewBottomConstraints: NSLayoutConstraint!
#IBOutlet weak var viewTextViewContainer: ViewCustom!
#IBOutlet weak var txtViewContainerHeightConstraints: NSLayoutConstraint!
#IBOutlet weak var txtViewHeightConstraints: NSLayoutConstraint!
#IBOutlet var lblUserName: UILabel!
#IBOutlet var userImg: UIImageView!
#IBOutlet weak var txtView: IQTextView!
#IBOutlet weak var tblViewChat: UITableView!
#IBOutlet weak var bottomViewBottomConstraints: NSLayoutConstraint!
#IBOutlet weak var btnSend: UIButton!
var grpId = String()
var getMessageTimer: Timer!
var scrollEnable : Bool = false
var imagePicker : UIImagePickerController? = nil
var imageData : Data?
var groupName = String()
var groupImage = String()
var isFromNotification = Bool()
var strId = String()
var objChatVM = ChatViewModel()
var getMessageId = String()
var userImage:URL? = nil
var userName = String()
override func viewDidLoad() {
super.viewDidLoad()
popWithSwipe()
txtView.autocorrectionType = .no
lblUserName.text = userName
/* if userImage != nil
{
userImg.kf.setImage(with:userImage)
}
else
{
userImg.image = UIImage(named: "user")
}*/
userImg.kf.setImage(with:userImage, completionHandler: {
(image, error, cacheType, imageUrl) in
if image != nil{
self.userImg.image = image
}
else{
self.userImg.image = #imageLiteral(resourceName: "user")
}
})
IQKeyboardManager.shared.enable = false
IQKeyboardManager.shared.enableAutoToolbar = false
tblViewChat.dataSource = self
tblViewChat.delegate = self
tblViewChat.estimatedRowHeight = 70.0
tblViewChat.rowHeight = UITableViewAutomaticDimension
txtView.delegate = self
// txtView.textContainerInset = UIEdgeInsets(top: 0, left: 2, bottom: 0, right: 2)
let tapGestuer = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
view.addGestureRecognizer(tapGestuer)
tapGestuer.delegate = self
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
if getMessageTimer != nil{
getMessageTimer.invalidate()
}
getMessageTimer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(getMessageApi), userInfo: nil, repeats: true)
IQKeyboardManager.shared.enable = false
IQKeyboardManager.shared.enableAutoToolbar = false
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
getMessageTimer.invalidate()
NotificationCenter.default.removeObserver(self)
}
// MARK:- Get messages from server
#objc func getMessageApi(){
objChatVM.getMessage(param:strId) {status in
if status{
self.tblViewChat.reloadData()
if(self.objChatVM.getNumberOfMessage() != 0){
self.tblViewChat.scrollToRow(at: IndexPath(item: self.objChatVM.getNumberOfMessage()-1, section: 0), at: .bottom, animated: false)
}
}
}
}
#objc func handleTap(sender: UITapGestureRecognizer) {
txtView.resignFirstResponder()
}
// Enable IQKEYBoard manager here for handle keyboard at other controller which has disabled in viewdidload or viewwillappear
override func viewDidDisappear(_ animated: Bool) {
IQKeyboardManager.shared.enable = true
IQKeyboardManager.shared.enableAutoToolbar = true
}
// MARK:- Gesutrue Delegate Methods
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
// Handle here tap on table view and inside cell for dismiss keyboard while tap outside on the screen
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if (touch.view is SenderTblCell || touch.view is ReceiverTblCell ) {
return false
}
if (touch.view?.superview is SenderTblCell || touch.view?.superview is ReceiverTblCell) {
return false
}
if (touch.view?.superview?.superview is SenderTblCell || touch.view?.superview?.superview is ReceiverTblCell) {
return false
}
if (touch.view?.superview?.superview?.superview is SenderTblCell || touch.view?.superview?.superview?.superview is ReceiverTblCell) {
return false
}
if(touch.view?.superview?.isDescendant(of: SenderTblCell().contentView))! || (touch.view?.superview?.isDescendant(of: ReceiverTblCell().contentView))!{
return false
}
return true // handle the touch
}
// MARK:- KeyBoard will show
#objc func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
var safeArea = 0
if UIDevice().userInterfaceIdiom == .phone || UIDevice().userInterfaceIdiom == .pad{
switch UIScreen.main.nativeBounds.height {
case 2436:
bottomViewBottomConstraints.constant = -keyboardSize.height + 30
self.view.layoutIfNeeded()
default:
if #available(iOS 11.0, *) {
let window = UIApplication.shared.keyWindow
safeArea = Int(window?.safeAreaInsets.bottom ?? 0.0)
}
bottomViewBottomConstraints.constant = -keyboardSize.height + CGFloat(safeArea) - 10
self.view.layoutIfNeeded()
}
}
}
}
// MARK:- KeyBoard will hide
#objc func keyboardWillHide(notification: NSNotification) {
bottomViewBottomConstraints.constant = -30
self.view.layoutIfNeeded()
}
#IBAction func btnSendAction(_ sender: Any) {
let param = ["userId":strId,"message":txtView.text!]
objChatVM.sendMessage(param: param) { (status) in
self.txtView.text = ""
self.textViewDidChange(self.txtView)
}
}
//MARK:- TextView Delegate Methods
func textViewDidChange(_ textView: UITextView) {
if textView.text == ""{
//textView.translatesAutoresizingMaskIntoConstraints = true
// txtViewHeightConstraints.constant = 100.0
// btnSend.setImage(#imageLiteral(resourceName: "attachment"), for: .normal)
}else{
// btnSend.setImage(#imageLiteral(resourceName: "sendMsg"), for: .normal)
}
var frame : CGRect = textView.bounds
frame.size.height = textView.contentSize.height
print(frame)
if(frame.height >= 100.0){
textView.isScrollEnabled = true
}
else{
textView.isScrollEnabled = false
txtView.frame.size = frame.size
}
if textView.text == ""{
txtViewContainerHeightConstraints.constant = 50.0
txtViewBottomConstraints.constant = 5.0
txtView.updateConstraints()
viewTextViewContainer.updateConstraintsIfNeeded()
viewTextViewContainer.updateConstraints()
viewTextViewContainer.layoutIfNeeded()
self.view.layoutIfNeeded()
}
}
func textViewDidEndEditing(_ textView: UITextView) {
}
func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
return true
}
// MARK:- TableView DataSource and Delegate Methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return objChatVM.getNumberOfMessage()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let messageUserId = objChatVM.getMessageUserFromId(index: indexPath.row)
print(UserViewModel.Shared().getUserId())
if(messageUserId == UserViewModel.Shared().getUserId()){
let cell = tblViewChat.dequeueReusableCell(withIdentifier: "senderCell") as! SenderTblCell
cell.lblMessage.text = objChatVM.getMessage(index: indexPath.row)
cell.lblDate.text = objChatVM.getDateTime(index: indexPath.row)
return cell
}
let cell = tblViewChat.dequeueReusableCell(withIdentifier: "receiverCell") as! ReceiverTblCell
cell.lblMessage.text = objChatVM.getMessage(index: indexPath.row)
cell.lblDate.text = objChatVM.getDateTime(index: indexPath.row)
cell.lblName.text = objChatVM.getFullNameOfUserFrom(index: indexPath.row)
let url = URL(string:objChatVM.getUserFromImage(index:indexPath.row))
cell.imgView.kf.indicatorType = .activity
cell.imgView.kf.setImage(with:url)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableViewAutomaticDimension
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
txtView.resignFirstResponder()
}
// MARK: Side Menu Button Action
#IBAction func btnSideMenuActn(_ sender: UIButton) {
self.pushViewControl(ViewControl:"SideMenuController")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is how the message from my server in my logs looks like
message = "Am+good.+How+are+you+my+student%3F";
Use removingPercentEncoding and some of the text such as + doesn't seem to generated by urlEncoding if they are created by code then use both in combination:
message = "Am+good.+How+are+you+my+student%3F"
let decodedMessage = message.removingPercentEncoding?.replacingOccurrences(of: "+", with: " ")
print(decodedMessage)

How to set a UIPickerView selected value from Realm?

I have setup a viewcontroller where there are 7 "questions" and 7 "answers". I've created a UIPickerView that allows users to select their answer when they click on the answer's UITextField, and save it in realm.
However, when a user has already selected an answer (example: "Agree"), "Agree" doesn't show up as the selected row in the UIPickerView when I click the UITextField for that answer.
How do I set the default or "selectedrow" for the UIPickerview to the answer that is displayed in the UITextField and is saved in Realm?
import UIKit
import RealmSwift
class QuestionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupDelegateForPickerView()
setupDelegatesForTextFields()
}
override func viewWillAppear(_ animated: Bool) {
loadAnswers()
}
#IBOutlet weak var Question1TextField: UITextField!
#IBOutlet weak var Question2TextField: UITextField!
#IBOutlet weak var Question3TextField: UITextField!
#IBOutlet weak var Question4TextField: UITextField!
#IBOutlet weak var Question5TextField: UITextField!
#IBOutlet weak var Question6TextField: UITextField!
#IBOutlet weak var Question7TextField: UITextField!
// Setting up a UIPickerview from the ToolbarPickerView class
let realm = try! Realm()
var answers: Results<Answer>?
var answerArray = [UITextField]()
func loadAnswers() {
var answersGiven = realm.objects(Answer.self).filter("id = 1")
for answer in answersGiven {
Question1TextField.text = answer.Answer1
Question2TextField.text = answer.Answer2
Question3TextField.text = answer.Answer3
Question4TextField.text = answer.Answer4
Question5TextField.text = answer.Answer5
Question6TextField.text = answer.Answer6
Question7TextField.text = answer.Answer7
}
}
let pickerView = ToolbarPickerView()
let Menu = ["Strongly Disagree",
"Disagree",
"Neutral",
"Agree",
"Strongly Agree"]
var selectedMenu : String?
func setupDelegatesForTextFields() {
//appending textfields in an array
answerArray += [Question1TextField, Question2TextField, Question3TextField, Question4TextField, Question5TextField, Question6TextField, Question7TextField]
//using the array to set up the delegates, inputview for pickerview and also the inputAccessoryView for the toolbar
for answer in answerArray {
answer.delegate = self
answer.inputView = pickerView
answer.inputAccessoryView = pickerView.toolbar
}
}
func setupDelegateForPickerView() {
pickerView.dataSource = self
pickerView.delegate = self
pickerView.toolbarDelegate = self
}
func setDefaultValue(item: String, inComponent: Int){
if let indexPosition = Menu.firstIndex(of: item){
pickerView.selectRow(indexPosition, inComponent: inComponent, animated: true)
}
}
// Dismissing Keyboard on tapped
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
}
extension QuestionViewController : UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
self.pickerView.reloadAllComponents()
}
}
extension QuestionViewController : UIPickerViewDelegate, UIPickerViewDataSource {
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.Menu.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return self.Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let answer = Answer()
answer.id = 1
// Check if the textfield isFirstResponder.
if Question1TextField.isFirstResponder {
Question1TextField.text = self.Menu[row]
answer.Answer1 = Question1TextField.text
try! realm.write {
realm.create(Answer.self, value: ["id": 1, "Answer1": self.Menu[row]], update: .modified)
}
} else if Question2TextField.isFirstResponder {
Question2TextField.text = self.Menu[row]
answer.Answer2 = Question2TextField.text
try! realm.write {
realm.create(Answer.self, value: ["id": 1, "Answer2": self.Menu[row]], update: .modified)
}
} else if Question3TextField.isFirstResponder {
Question3TextField.text = self.Menu[row]
answer.Answer3 = Question3TextField.text
try! realm.write {
realm.create(Answer.self, value: ["id": 1, "Answer3": self.Menu[row]], update: .modified)
}
} else if Question4TextField.isFirstResponder {
Question4TextField.text = self.Menu[row]
answer.Answer4 = Question4TextField.text
try! realm.write {
realm.create(Answer.self, value: ["id": 1, "Answer4": self.Menu[row]], update: .modified)
}
} else if Question5TextField.isFirstResponder {
Question5TextField.text = self.Menu[row]
answer.Answer5 = Question5TextField.text
try! realm.write {
realm.create(Answer.self, value: ["id": 1, "Answer5": self.Menu[row]], update: .modified)
}
} else if Question6TextField.isFirstResponder {
Question6TextField.text = self.Menu[row]
answer.Answer6 = Question6TextField.text
try! realm.write {
realm.create(Answer.self, value: ["id": 1, "Answer6": self.Menu[row]], update: .modified)
}
} else if Question7TextField.isFirstResponder {
Question7TextField.text = self.Menu[row]
answer.Answer7 = Question7TextField.text
try! realm.write {
realm.create(Answer.self, value: ["id": 1, "Answer7": self.Menu[row]], update: .modified)
}
} else {
//log errors
}
}
}
extension QuestionViewController: ToolbarPickerViewDelegate {
func didTapDone() {
let row = self.pickerView.selectedRow(inComponent: 0)
self.pickerView.selectRow(row, inComponent: 0, animated: false)
selectedMenu = self.Menu[row]
self.view.endEditing(true)
}
func didTapCancel() {
self.view.endEditing(true)
}
}
Here is the Toolbar Class just incase.
import UIKit
protocol ToolbarPickerViewDelegate: class {
func didTapDone()
func didTapCancel()
}
class ToolbarPickerView: UIPickerView {
public private(set) var toolbar: UIToolbar?
public weak var toolbarDelegate: ToolbarPickerViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.commonInit()
}
private func commonInit() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(self.doneTapped))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(self.cancelTapped))
toolBar.setItems([cancelButton, spaceButton, doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
toolBar.backgroundColor = UIColor(red: 0/255.0, green: 142.0/255.0, blue: 44.0/255.0, alpha: 0.5)
toolBar.tintColor = UIColor(red: 0/255.0, green: 142.0/255.0, blue: 44.0/255.0, alpha: 0.5)
UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor(red: 0/255.0, green: 142.0/255.0, blue: 44.0/255.0, alpha: 1.0),
NSAttributedString.Key.font: UIFont(name: "Clinton", size: 14)], for: UIControl.State.normal)
self.toolbar = toolBar
}
#objc func doneTapped() {
self.toolbarDelegate?.didTapDone()
}
#objc func cancelTapped() {
self.toolbarDelegate?.didTapCancel()
}
}
extension String {
// formatting text for currency textField
func currencyFormatting() -> String {
if let value = Double(self) {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.maximumFractionDigits = 0
if let str = formatter.string(for: value) {
return str
}
}
return ""
}
}

how to filter data with multiple buttons using delegate?

The Delegate that I am using is used to filter out the specified category using a delegate when a button is pressed in the FilterVC
what im struggling with is setting up buttons in the FilterVC so that filter works in the HomeVC
ive noticed that issue might be in my FilterVC when using the delegate in the #IBAction func acceptSelections where im getting the error Cannot convert value of type 'RoundButton?' to expected argument type 'String?' when calling the buttons when using the delegate to control which category
import UIKit
import Firebase
import FirebaseFirestore
class HomeViewController: UIViewController {
#IBOutlet weak var tableView: UITableView!
#IBOutlet var activeFiltersStackView: UIStackView!
#IBOutlet var stackViewHeightConstraint: NSLayoutConstraint!
#IBOutlet var jewelryFilterLbl: UILabel!
#IBOutlet var hatFilterLbl: UILabel!
#IBOutlet var shoeFilterLbl: UILabel!
#IBOutlet var apparelFilterLbl: UILabel!
#IBOutlet var gearFilterLbl: UILabel!
private lazy var baseQuery: Query = {
return Firestore.firestore().collection("products").limit(to: 50)
}()
fileprivate var query: Query?
lazy private var filters: (navigationController: UINavigationController,
filtersController: FilterViewController) = {
return FilterViewController.fromStoryboard(delegate: self)
}()
#IBAction func didTapClearBtn(_ sender: Any){
filters.filtersController.clearFilters()
controller(filters.filtersController, didSelectCategory: nil, sativa: nil, indica: nil, hybrid: nil, gear: nil)
}
var productSetup: [ProductList] = []
var products: ProductList?
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
// arranges products by store nearest you
fetchProducts { (products) in
self.productSetup = products.sorted(by: { $0.itemName < $1.itemName })
self.productListTableView.reloadData()
}
}
// fetches Firebase Data
func fetchProducts(_ completion: #escaping ([ProductList]) -> Void) {
let productQuery = Firestore.firestore().collection("products").limit(to: 50)
productQuery.addSnapshotListener { (snapshot, error) in
guard error == nil, let snapshot = snapshot, !snapshot.isEmpty else {
return
}
completion(snapshot.documents.compactMap( {ProductList(dictionary: $0.data())} ))
}
// shows Firestore data in log (not neccessary code just used to be seen in logs)
productQuery.getDocuments { (snapshot, error) in
if let error = error {
print("Oh no! Got an error! \(error.localizedDescription)")
return
}
guard let snapshot = snapshot else { return }
let allDocuments = snapshot.documents
for productDocument in allDocuments {
print("I have this product \(productDocument.data())")
}
}
}
}
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return productSetup.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell") as?
HomeCell else { return UITableViewCell() }
cell.configure(withProduct: productSetup[indexPath.row])
return cell
}
}
extension HomeViewController: FiltersViewControllerDelegate{
func query(withCategory jewelry: String?, hat: String?, shoe: String?, gear: String?, apparel: String?) -> Query {
if jewelry == nil && hat == nil && shoe == nil && gear == nil && apparel == nil {
stackViewHeightConstraint.constant = 0
activeFiltersStackView.isHidden = true
} else {
stackViewHeightConstraint.constant = 44
activeFiltersStackView.isHidden = false
}
var filtered = baseQuery
// Sort and Filter data
if let jewelry = jewelry, !jewelry.isEmpty {
filtered = filtered.whereField("category", isEqualTo: jewelry)
}
if let hat = hat, ! hat.isEmpty {
filtered = filtered.whereField("category", isEqualTo: hat)
}
if let shoe = shoe, !shoe.isEmpty {
filtered = filtered.whereField("category", isEqualTo: shoe)
}
if let gear = gear, !gear.isEmpty {
filtered = filtered.whereField("category", isEqualTo: gear)
}
if let apparel = apparel, !apparel.isEmpty {
filtered = filtered.whereField("category", isEqualTo: apparel)
}
return filtered
}
func controller(_ controller: FilterViewController,
didSelectCategory jewelry: String?,
hat: String?,
shoe: String?,
gear: String?,
apparel: String?) {
if jewelry == nil && hat == nil && shoe == nil && gear == nil && apparel == nil {
stackViewHeightConstraint.constant = 0
activeFiltersStackView.isHidden = true
} else {
stackViewHeightConstraint.constant = 44
activeFiltersStackView.isHidden = false
}
let filtered = query(withCategory: jewelry, hat: hat, shoe: shoe, gear: gear, apparel: apparel)
if let jewelry = jewelry, ! jewelry.isEmpty {
jewelryFilterLbl.text = jewelry
jewelryFilterLbl.isHidden = false
} else {
jewelryFilterLbl.isHidden = true
}
if let hat = hat, ! hat.isEmpty {
hatFilterLbl.text = hat
hatFilterLbl.isHidden = false
} else {
hatFilterLbl.isHidden = true
}
if let shoe = shoe, ! shoe.isEmpty {
shoeFilterLbl.text = shoe
shoeFilterLbl.isHidden = false
} else {
shoeFilterLbl.isHidden = true
}
if let gear = gear, !gear.isEmpty {
gearFilterLbl.text = gear
gearFilterLbl.isHidden = false
} else {
gearFilterLbl.isHidden = true
}
if let apparel = apparel, ! apparel.isEmpty {
apparelFilterLbl.text = apparel
apparelFilterLbl.isHidden = false
} else {
apparelFilterLbl.isHidden = true
}
query = filtered
}
}
import UIKit
import Firebase
protocol FiltersViewControllerDelegate: NSObjectProtocol {
func controller(_ controller: FilterViewController,
didSelectCategory jewelry: String?,
hat: String?,
shoe: String?,
gear: String?,
apparel: String?)
}
class FilterViewController: UIViewController {
#IBOutlet weak var jewelryBtn: RoundButton!
#IBOutlet weak var hatBtn: RoundButton!
#IBOutlet weak var shoeBtn: RoundButton!
#IBOutlet weak var gearBtn: RoundButton!
#IBOutlet weak var apparelBtn: RoundButton!
static func fromStoryboard(delegate: FiltersViewControllerDelegate? = nil) ->
(navigationController: UINavigationController, filtersController: FilterViewController) {
let navController = UIStoryboard(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "FiltersViewController")
as! UINavigationController
let controller = navController.viewControllers[0] as! FilterViewController
controller.delegate = delegate
return (navigationController: navController, filtersController: controller)
}
weak var delegate: FiltersViewControllerDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func filterSelect(_ sender: Any) {
if let button : UIButton = sender as? UIButton
{
button.isSelected = !button.isSelected
if (button.isSelected)
{
button.backgroundColor = .green
}
else
{
button.backgroundColor = .gray
}
}
}
func clearFilters() {
apparelBtn.isSelected = false
jewelryBtn.isSelected = false
shoeBtn.isSelected = false
hatBtn.isSelected = false
gearBtn.isSelected = false
}
#IBAction func closeFilter(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
#IBAction func acceptSelections(_ sender: Any) {
delegate?.controller(self, //Problem integrating the buttons to get the correct category
didSelectCategory: jewelryBtn,
hat: hatBtn,
shoe: shoeBtn,
gear: gearBtn,
apparel: apparelBtn)
dismiss(animated: true)
}
}
As the filter functionality is pure boolean I recommend to just return the isSelected values of the buttons
protocol FiltersViewControllerDelegate: NSObjectProtocol {
func controller(_ controller: FilterViewController,
didSelectCategory jewelry: Bool,
hat: Bool,
shoe: Bool,
gear: Bool,
apparel: Bool)
}
And call it
#IBAction func acceptSelections(_ sender: Any) {
delegate?.controller(self,
didSelectCategory: jewelryBtn.isSelected,
hat: hatBtn.isSelected,
shoe: shoeBtn.isSelected,
gear: gearBtn.isSelected,
apparel: apparelBtn.isSelected)
dismiss(animated: true)
}
It seems to be a multiple choice selection so you have to combine the options in the query.

Update multiple UILabels in custom UITableViewCell with data from multiple corresponding UITextFields? Swift

I have a ViewController where a user can input their data in 4 UITextFields, populated by UIPickerViews, and when the user presses a save button the data is supposed to update the corresponding UILabels in the corresponding custom UITableViewCell.
See link below.
TableView and Input ViewControllers with arrows showing corresponding UILabels and UITextFields
Currently, with the code provided, all UILabels in the custom UITableViewCell display the same data.
See link below.
Current TableViewCell output in Simulator
I suspect I'm having issues with either this part in the RunFeedViewController
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "runFeedCell1", for: indexPath) as! Mountain1TableViewCell
cell.mountain1RunTypeLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunNameLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunSnowLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunDateLabel?.text = runFeedList[indexPath.item]
return (cell)
}
and/or this part in the Mountain1RunInputViewController
#IBAction func saveMountain1Run(_ sender: Any) {
if (mountain1RunDateTextField.text != "")
{
runFeedList.append(mountain1RunDateTextField.text!)
mountain1RunDateTextField.text = ""
UserDefaults.standard.set(runFeedList, forKey: "runFeedList")
}
}
What am I missing to make all 4 UILabels work with their corresponding UITextFields?.
Here is the code for the RunFeedViewController with the UITableView.
import UIKit
import Firebase
import FirebaseAuth
import FirebaseDatabase
var runFeedList = [String]()
class RunFeedViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var runFeedListTable: UITableView!
var ref: DatabaseReference?
var databaseHandle: DatabaseHandle?
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return (runFeedList.count)
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "runFeedCell1", for: indexPath) as! Mountain1TableViewCell
cell.mountain1RunTypeLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunNameLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunSnowLabel?.text = runFeedList[indexPath.item]
cell.mountain1RunDateLabel?.text = runFeedList[indexPath.item]
return (cell)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath){
if editingStyle == UITableViewCellEditingStyle.delete
{
runFeedList.remove(at: indexPath.row)
UserDefaults.standard.set(runFeedList, forKey: "runFeedList")
runFeedListTable.reloadData()
}
}
override func viewDidAppear(_ animated: Bool) {
runFeedListTable.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
if UserDefaults.standard.object(forKey: "runFeedList") != nil
{
runFeedList = UserDefaults.standard.object(forKey: "runFeedList") as! [String]
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func logOutAction(_ sender: Any) {
if Auth.auth().currentUser != nil {
do {
try Auth.auth().signOut()
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SignUp")
present(vc, animated: true, completion: nil)
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
}
Here is the code for the Mountain1RunInputViewController where the user inputs the data in the 4 UITextFields.
import UIKit
var mountain1RunTypeArray = ["1", "2", "3", "4"]
var mountain1RunNameArray1 = ["1A","1B","1C", "1D"]
var mountain1RunNameArray2 = ["2A","2B","2C", "2D"]
var mountain1RunNameArray3 = ["3A","3B","3C", "3D"]
var mountain1RunNameArray4 = ["4A","4B","4C", "4D"]
var mountain1RunSnowArray = ["Good", "Bad"]
var mountain1SelectedItemsArray = [String]()
var mountain1RunTypeTextField: String = ""
var mountain1RunNameTextField: String = ""
var mountain1RunSnowTextField: String = ""
var mountain1RunDateTextField: String = ""
class Mountain1RunInputViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate{
var pickerView1 = UIPickerView()
var pickerView2 = UIPickerView()
var pickerView3 = UIPickerView()
var pickerView4 = UIDatePicker()
#IBOutlet weak var mountain1RunTypeTextField: UITextField!
#IBOutlet weak var mountain1RunNameTextField: UITextField!
#IBOutlet weak var mountain1RunSnowTextField: UITextField!
#IBOutlet weak var mountain1RunDateTextField: UITextField!
#IBAction func saveMountain1Run(_ sender: Any) {
if (mountain1RunDateTextField.text != "")
{
runFeedList.append(mountain1RunDateTextField.text!)
mountain1RunDateTextField.text = ""
UserDefaults.standard.set(runFeedList, forKey: "runFeedList")
}
}
override func viewDidLoad() {
super.viewDidLoad()
createToolbar()
pickerView1 = UIPickerView()
pickerView2 = UIPickerView()
pickerView3 = UIPickerView()
pickerView4 = UIDatePicker()
pickerView1.delegate = self
pickerView1.dataSource = self
pickerView2.delegate = self
pickerView2.dataSource = self
pickerView3.delegate = self
pickerView3.dataSource = self
pickerView1.tag = 0
pickerView2.tag = 1
pickerView3.tag = 2
pickerView4.tag = 3
self.mountain1RunTypeTextField.inputView = self.pickerView1;
self.mountain1RunNameTextField.inputView = self.pickerView2;
self.mountain1RunSnowTextField.inputView = self.pickerView3;
self.mountain1RunDateTextField.inputView = self.pickerView4;
pickerView4.addTarget(self, action: #selector(datePickerValueChanged(sender:)), for: .valueChanged)
pickerView4.datePickerMode = UIDatePickerMode.dateAndTime
}
func createToolbar() {
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let cancelButton1 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker1))
let cancelButton2 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker2))
let cancelButton3 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker3))
let cancelButton4 = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(Mountain1RunInputViewController.cancelPicker4))
// Tool bar for 1st UIPickerView
let toolBar1 = UIToolbar()
toolBar1.sizeToFit()
toolBar1.barTintColor = .black
toolBar1.tintColor = .white
let doneButton1 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton1(sender:)))
toolBar1.setItems([cancelButton1,spaceButton,doneButton1], animated: false)
toolBar1.isUserInteractionEnabled = true
mountain1RunTypeTextField.inputAccessoryView = toolBar1
// Tool bar for 2nd UIPickerView
let toolBar2 = UIToolbar()
toolBar2.sizeToFit()
toolBar2.barTintColor = .black
toolBar2.tintColor = .white
let doneButton2 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton2(sender:)))
toolBar2.setItems([cancelButton2,spaceButton,doneButton2], animated: false)
toolBar2.isUserInteractionEnabled = true
mountain1RunNameTextField.inputAccessoryView = toolBar2
// Tool bar for 3rd UIPickerView
let toolBar3 = UIToolbar()
toolBar3.sizeToFit()
toolBar3.barTintColor = .black
toolBar3.tintColor = .white
let doneButton3 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton3(sender:)))
toolBar3.setItems([cancelButton3,spaceButton,doneButton3], animated: false)
toolBar3.isUserInteractionEnabled = true
mountain1RunSnowTextField.inputAccessoryView = toolBar3
// Tool bar for UIDatePicker
let toolBar4 = UIToolbar()
toolBar4.sizeToFit()
toolBar4.barTintColor = .black
toolBar4.tintColor = .white
let doneButton4 = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(Mountain1RunInputViewController.doneButton4))
toolBar4.setItems([cancelButton4,spaceButton,doneButton4], animated: false)
toolBar4.isUserInteractionEnabled = true
mountain1RunDateTextField.inputAccessoryView = toolBar4
}
func cancelPicker1(){
self.view.endEditing(true)
}
func cancelPicker2(){
self.view.endEditing(true)
}
func cancelPicker3(){
self.view.endEditing(true)
}
func cancelPicker4(){
self.view.endEditing(true)
}
// Done button for 1st UIPickerView
func doneButton1(sender: AnyObject) {
let row1 = pickerView1.selectedRow(inComponent: 0);
pickerView(pickerView1, didSelectRow: row1, inComponent:0)
view.endEditing(true)
}
// Done button for 2nd UIPickerView
func doneButton2(sender: AnyObject) {
let row2 = pickerView2.selectedRow(inComponent: 0);
pickerView(pickerView2, didSelectRow: row2, inComponent:0)
view.endEditing(true)
}
// Done button for 3rd UIPickerView
func doneButton3(sender: AnyObject) {
let row3 = pickerView3.selectedRow(inComponent: 0);
pickerView(pickerView3, didSelectRow: row3, inComponent:0)
view.endEditing(true)
}
// Done button for UIDatePicker
func doneButton4(){
let formatter = DateFormatter()
formatter.dateStyle = DateFormatter.Style.long
formatter.timeStyle = DateFormatter.Style.short
mountain1RunDateTextField.text = formatter.string(from: pickerView4.date)
self.view.endEditing(true)
}
func dismissKeyboard() {
self.view.endEditing(true)
}
func datePickerValueChanged(sender:UIDatePicker) {
let dateFormatter = DateFormatter()
pickerView4.datePickerMode = UIDatePickerMode.dateAndTime
mountain1RunDateTextField.text = dateFormatter.string(from: sender.date)
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView.tag == 0 {
return mountain1RunTypeArray.count
} else if pickerView.tag == 1 {
return mountain1SelectedItemsArray.count
} else if pickerView.tag == 2 {
return mountain1RunSnowArray.count
}
return 1
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView.tag == 0 {
return mountain1RunTypeArray[row]
} else if pickerView.tag == 1 {
return mountain1SelectedItemsArray[row]
} else if pickerView.tag == 2 {
return mountain1RunSnowArray[row]
}
return ""
}
var selectedRow: Int = 0
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedRow = row
if pickerView == pickerView1 {
mountain1RunTypeTextField.text = mountain1RunTypeArray[row]
switch row {
case 0:
mountain1SelectedItemsArray = mountain1RunNameArray1;
case 1:
mountain1SelectedItemsArray = mountain1RunNameArray2
case 2:
mountain1SelectedItemsArray = mountain1RunNameArray3
case 3:
mountain1SelectedItemsArray = mountain1RunNameArray4
default:
mountain1SelectedItemsArray = []
}
pickerView2.reloadAllComponents()
} else if pickerView == pickerView2 {
let item = mountain1SelectedItemsArray[row]
if mountain1SelectedItemsArray == mountain1RunNameArray1 {
mountain1RunNameTextField.text = item
} else if mountain1SelectedItemsArray == mountain1RunNameArray2 {
mountain1RunNameTextField.text = item
} else if mountain1SelectedItemsArray == mountain1RunNameArray3 {
mountain1RunNameTextField.text = item
} else if mountain1SelectedItemsArray == mountain1RunNameArray4 {
mountain1RunNameTextField.text = item
}
}
if pickerView.tag == 2 {
mountain1RunSnowTextField.text = mountain1RunSnowArray[row]
}
}
}
Here is the code for corresponding prototype cell.
import UIKit
class Mountain1TableViewCell: UITableViewCell {
#IBOutlet weak var mountain1RunTypeLabel: UILabel!
#IBOutlet weak var mountain1RunNameLabel: UILabel!
#IBOutlet weak var mountain1RunSnowLabel: UILabel!
#IBOutlet weak var mountain1RunDateLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}