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 ""
}
}
Related
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)
I am trying to build something (I am new to Xcode and swift) where I can choose a meal for a day from an array with Picker View, and I want my choice to display in that specific day's textfield. I have got this working, but for 1 day only. How can I get this same function working for all (7) days?
I managed to get the picker view when click on next textfield as well (Tuesday), but as I choose from the list the Mondays textfield will follow what I am doing for Tuesday. They are mirrored. I do get that I should probably make something to get thatTuesday-Picker unique somehow, but that's where Im stuck. I don't know what to change/write. Anyone with any ideas? I have googled around and find a lot regarding picker views but nothing for how they can been used in this specific way...
//
// ViewController.swift
// dropdown
//
// Created by -- on 2019-08-26.
// Copyright © 2019 --. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
// the menu
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
let tuesdayMenu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
//When a menu from the list is selected, it will be shown as a string
var mondaySelectedMenu: String?
var tuesdaySelectedMenu: String?
override func viewDidLoad() {
super.viewDidLoad()
//Call on these functions when loaded
createMondayMenuPicker()
createTuesdayMenuPicker()
createToolbar()
}
// This is the pickerView
func createMondayMenuPicker() {
let mondayMenuPicker = UIPickerView()
mondayMenuPicker.delegate = self
monday.inputView = mondayMenuPicker
}
func createTuesdayMenuPicker() {
let tuesdayMenuPicker = UIPickerView()
tuesdayMenuPicker.delegate = self
tuesday.inputView = tuesdayMenuPicker
}
// This is the "DONE" button
func createToolbar() {
let toolBar = UIToolbar()
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "DONE", style: .plain, target: self, action: #selector(ViewController.dismissKeyboard))
toolBar.setItems([doneButton], animated: false)
toolBar.isUserInteractionEnabled = true
monday.inputAccessoryView = toolBar
tuesday.inputAccessoryView = toolBar
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
// This is the details for the pickerView
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return Menu.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return Menu[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
mondaySelectedMenu = Menu[row]
tuesdaySelectedMenu = tuesdayMenu[row]
monday.text = mondaySelectedMenu
tuesday.text = tuesdaySelectedMenu
}
}
So, I want to call on that same array when click on all seven days but I want to display the unique choices for everyday chosen from that list. Any ideas? Thanks a lot!
One way to achieve this is to do using the below approach. I have separated out toolbar functionality into its own class.
Create a new class pickerview's toolbar (in this case i have called ToolbarPickerView.swift)
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.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
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
self.toolbar = toolBar
}
#objc func doneTapped() {
self.toolbarDelegate?.didTapDone()
}
#objc func cancelTapped() {
self.toolbarDelegate?.didTapCancel()
}
}
In ViewController
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var monday: UITextField!
#IBOutlet weak var tuesday: UITextField!
#IBOutlet weak var wednesday: UITextField!
#IBOutlet weak var thursday: UITextField!
#IBOutlet weak var friday: UITextField!
#IBOutlet weak var saturday: UITextField!
#IBOutlet weak var sunday: UITextField!
var daysArray = [UITextField]()
let pickerView = ToolbarPickerView()
let Menu = ["Palak Paner",
"Spagetti Köttfärssås",
"Thai Haloumi",
"Thai Quorn",
"Linssoppa",
"SparrisPasta",
"Gröt",
"Gulasch"]
var selectedMenu : String?
override func viewDidLoad() {
super.viewDidLoad()
setupDelegateForPickerView()
setupDelegatesForTextFields()
}
func setupDelegatesForTextFields() {
//appending textfields in an array
daysArray += [monday, tuesday, wednesday, thursday, friday, saturday, sunday]
//using the array to set up the delegates, inputview for pickerview and also the inputAccessoryView for the toolbar
for day in daysArray {
day.delegate = self
day.inputView = pickerView
day.inputAccessoryView = pickerView.toolbar
}
}
func setupDelegateForPickerView() {
pickerView.dataSource = self
pickerView.delegate = self
pickerView.toolbarDelegate = self
}
}
Create an extension for textfield delegate
extension ViewController : UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
self.pickerView.reloadAllComponents()
}
}
Extension for pickerview and toolbar
extension ViewController : 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) {
// Check if the textfield isFirstResponder.
if monday.isFirstResponder {
monday.text = self.Menu[row]
} else if tuesday.isFirstResponder {
tuesday.text = self.Menu[row]
} else if wednesday.isFirstResponder {
wednesday.text = self.Menu[row]
} else if thursday.isFirstResponder {
thursday.text = self.Menu[row]
} else if friday.isFirstResponder {
friday.text = self.Menu[row]
} else if saturday.isFirstResponder {
saturday.text = self.Menu[row]
} else if sunday.isFirstResponder {
sunday.text = self.Menu[row]
} else {
//log errors
}
}
}
extension ViewController: 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)
}
}
PickerView's didSelectRow function can be simplified by changing it to below
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
for day in daysArray {
if day.isFirstResponder {
day.text = self.Menu[row]
}
}
}
Hopefully this answer will help you.
Create a common picker class like below:
class PKMultiPicker: UIPickerView, UIPickerViewDelegate, UIPickerViewDataSource {
internal typealias PickerDone = (_ firstValue: String, _ secondValue: String) -> Void
private var doneBlock : PickerDone!
private var firstValueArray : [String]?
private var secondValueArray = [String]()
static var noOfComponent = 2
class func openMultiPickerIn(_ textField: UITextField? , firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, titles: [String]?, toolBarTint: UIColor = UIColor.black, doneBlock: #escaping PickerDone) {
let picker = PKMultiPicker()
picker.doneBlock = doneBlock
picker.openPickerInTextField(textField, firstComponentArray: firstComponentArray, secondComponentArray: secondComponentArray, firstComponent: firstComponent, secondComponent: secondComponent, toolBarTint: toolBarTint)
if titles != nil {
let label = UILabel(frame: CGRect(x: UIScreen.main.bounds.size.width/4 - 10, y: 0, width: 100, height: 30))
label.text = titles![0].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
if PKMultiPicker.noOfComponent > 1 {
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 30))
label.text = titles![1].uppercased()
label.font = UIFont.boldSystemFont(ofSize: 18)
picker.addSubview(label)
} else {
label.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 30)
label.textAlignment = NSTextAlignment.center
}
}
}
private func openPickerInTextField(_ textField: UITextField?, firstComponentArray: [String], secondComponentArray: [String], firstComponent: String?, secondComponent: String?, toolBarTint: UIColor = UIColor.black) {
firstValueArray = firstComponentArray
secondValueArray = secondComponentArray
self.delegate = self
self.dataSource = self
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(pickerCancelButtonTapped))
cancelButton.tintColor = toolBarTint
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.done, target: self, action: #selector(pickerDoneButtonTapped))
doneButton.tintColor = toolBarTint
let spaceButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.flexibleSpace, target: nil, action:nil)
let toolbar = UIToolbar()
toolbar.sizeToFit()
let array = [cancelButton, spaceButton, doneButton]
toolbar.setItems(array, animated: true)
toolbar.backgroundColor = UIColor.lightText
textField?.inputView = self
textField?.inputAccessoryView = toolbar
let index = self.firstValueArray?.index(where: {$0.lowercased() == (firstComponent ?? "").lowercased() })
self.selectRow(index ?? 0, inComponent: 0, animated: true)
if PKMultiPicker.noOfComponent > 1 {
let index1 = self.secondValueArray.index(where: {$0.lowercased() == (secondComponent ?? "").lowercased() })
self.selectRow(index1 ?? 0, inComponent: 1, animated: true)
}
}
#IBAction private func pickerCancelButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
}
#IBAction private func pickerDoneButtonTapped(){
UIApplication.shared.keyWindow?.endEditing(true)
let index1 : Int?
let firstValue : String?
index1 = self.selectedRow(inComponent: 0)
if firstValueArray?.count == 0{return}
else{firstValue = firstValueArray?[index1!]}
var index2 :Int!
var secondValue: String!
if PKMultiPicker.noOfComponent > 1 {
index2 = self.selectedRow(inComponent: 1)
secondValue = secondValueArray[index2]
}
self.doneBlock((firstValue ?? ""), (secondValue ?? ""))
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == 0 {
return firstValueArray!.count
}
return secondValueArray.count
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return PKMultiPicker.noOfComponent
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
switch component {
case 0:
return firstValueArray?[row]
case 1:
return secondValueArray[row]
default:
return ""
}
}
}
Example Code to open picker and manage selection, there are some more options, you can manage number of components also:-
PKMultiPicker.noOfComponent = 1
PKMultiPicker.openMultiPickerIn(textField, firstComponentArray: ["Apple", "Mango","Grapes","Pine apple"], secondComponentArray: [], firstComponent: textField.text, secondComponent: nil, titles: nil, toolBarTint: AppColors.themeGreen) { (firstSelect, secondSelect) in
print("first select : \(firstSelect)")
textField.text = firstSelect // you can set text here to the respective text field.
}
Here #pawan_kumar has described a way for using same picker view for multiple textfields with same data. but you can bind different data sources for that as well. https://stackoverflow.com/a/60631018/10505343 has a sample code for that. here I use UITextField.isFirstResponder to decide what data should be loaded to the picker view. Hope this answer also will be helpful for you.
I'm trying to export the result of my 'pickerViews' right beside each other in a numeric form, as in if the 'pickerViews' have selected "A", "B" and "C", I want a 'func' to print them out on a 'UILabel' as "123" (Each number for each letter). This is how I've coded my 'pickerView' :
import UIKit
class PickerTextField: UITextField,UIPickerViewDelegate,UIPickerViewDataSource {
let pickerView = UIPickerView()
var itemList = [String]()
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
#objc func textEdited(_ sender:PickerTextField)
{
self.text = itemList[pickerView.selectedRow(inComponent: 0)]
}
override func draw(_ rect: CGRect) {
super.draw(rect)
self.tintColor = UIColor.clear
self.addTarget(self, action: #selector(textEdited(_:)), for: .editingChanged)
pickerView.showsSelectionIndicator = true
pickerView.delegate = self
pickerView.dataSource = self
self.inputView = pickerView
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
toolBar.items = [cancelButton, spaceButton, doneButton]
self.inputAccessoryView = toolBar
}
#objc func doneBtnAction(_ sender:UIBarButtonItem) {
resignFirstResponder()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return itemList.count
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let title = itemList[row]
return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor:UIColor.black])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.text = itemList[row]
}
}
class ViewController: UIViewController {
#IBOutlet weak var servicesField: PickerTextField!
#IBOutlet weak var brandsField: PickerTextField!
#IBOutlet weak var modelsField: PickerTextField!
#IBOutlet weak var Capacity: UITextField!
#IBOutlet weak var Details: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
servicesField.itemList = ["Select", "Services", "others"]
brandsField.itemList = ["Select" ,"Apple", "Samsung"]
modelsField.itemList = ["Select", "5", "5s"]
}
}
any help here? Thanks.
Create a struct for your data
struct Item {
var id:Int
var title:String
}
Change PickerTextFiled class to use this struct
class PickerTextField: UITextField,UIPickerViewDelegate,UIPickerViewDataSource {
let pickerView = UIPickerView()
var itemList = [Item]()
var selectedItem:Item?
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
#objc func textEdited(_ sender:PickerTextField)
{
self.text = itemList[pickerView.selectedRow(inComponent: 0)].title
}
override func draw(_ rect: CGRect) {
super.draw(rect)
self.tintColor = UIColor.clear
self.addTarget(self, action: #selector(textEdited(_:)), for: .editingChanged)
pickerView.showsSelectionIndicator = true
pickerView.delegate = self
pickerView.dataSource = self
self.inputView = pickerView
let toolBar = UIToolbar()
toolBar.barStyle = UIBarStyle.default
toolBar.isTranslucent = true
toolBar.tintColor = .black
toolBar.sizeToFit()
let doneButton = UIBarButtonItem(title: "Done", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
let spaceButton = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil)
let cancelButton = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(doneBtnAction(_:)))
toolBar.items = [cancelButton, spaceButton, doneButton]
self.inputAccessoryView = toolBar
}
#objc func doneBtnAction(_ sender:UIBarButtonItem) {
resignFirstResponder()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return itemList.count
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
let title = itemList[row].title
return NSAttributedString(string: title, attributes: [NSAttributedStringKey.foregroundColor:UIColor.black])
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.selectedItem = itemList[row]
self.text = itemList[row].title
}
}
Then you can get the id wherever you need
class ViewController: UIViewController {
#IBOutlet weak var servicesField: PickerTextField!
#IBOutlet weak var brandsField: PickerTextField!
#IBOutlet weak var modelsField: PickerTextField!
override func viewDidLoad() {
super.viewDidLoad()
servicesField.itemList = [Item(id: -1, title: "Select"),Item(id: -1, title: "Services"),Item(id: -1, title: "others")]
brandsField.itemList = [Item(id: -1, title: "Select"),Item(id: -1, title: "Apple"),Item(id: -1, title: "Samsung")]
modelsField.itemList = [Item(id: -1, title: "Select"),Item(id: -1, title: "5"),Item(id: -1, title: "5s")]
}
func printAll() {
if let servicesFieldId = servicesField.selectedItem?.id, let brandsFieldId = brandsField.selectedItem?.id, let modelsFieldId = servicesField.selectedItem?.id {
label.text = String(servicesFieldId) + String(brandsFieldId) + String(modelsFieldId)
}
}
}
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.
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
}
}