From "var myValue:[Double]..." and "var activeCurrency:Double = 0;" to the third pickerview code, I am not sure what to do in order to fix the "self.myValues.append((Url as? Double)!)" so that my app displays the currency amount. I have searched everywhere, and have no luck in finding anything. You are my last hope, please help. I'm still fairly new to coding, so I may not know the certain jargon.
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var myCurrency:[String] = []
var myValues:[Double] = []
var activeCurrency:Double = 0;
//OBJECTS
#IBOutlet weak var textbox: UITextField!
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var output: UILabel!
//CREATING PICKER VIEW
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return myCurrency.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return myCurrency[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
activeCurrency = myValues[row]
}
//BUTTON
#IBAction func action(_ sender: AnyObject) {
if (textbox.text != "") {
output.text = String(Double(textbox.text!)! * activeCurrency)
}
}
override func viewDidLoad() {
super.viewDidLoad()
//DATA GRABBING
let url = URL(string: "https://min-api.cryptocompare.com/data/all/coinlist")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil {
print ("ERROR")
}
else {
if let content = data {
do {
let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
if let rates = myJson["Data"] as? NSDictionary {
for (Name, Url) in rates {
self.myCurrency.append((Name as? String)!)
self.myValues.append((Url as? Double)!)
}
}
}
catch {
}
}
}
if data != nil {
DispatchQueue.main.async { // Correct
self.pickerView.reloadAllComponents()
}
}
}
task.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Related
how can I push the User Selection of a UIPicker to Firebase Database? So for example he hit on "male" than it will be stored in the Firebase Database...
My code for the UI Picker
class AddExtraData: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return data.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return data[row]
}
#IBOutlet var pickerView: UIPickerView!
let data = ["male", "female", "else"]
override func viewDidLoad() {
super.viewDidLoad()
pickerView.dataSource = self
pickerView.delegate = self
}
EDIT:
Database
Here is my database.
Now I want to get to write the data which is stored in seclectedYearPicker to the database.
var ref: DatabaseReference!
ref = Database.database().reference()
let selectedYearPicker = data[pickerView.selectedRow(inComponent: 0)]
print(selectedYearPicker)
let userID = Auth.auth().currentUser!.uid
ref.child("users").child(userID).setValue(["gender": selectedYearPicker])
}
If I make this, there will be a new dataset:
let db = Firestore.firestore()
db.collection("users").whereField("uid", isEqualTo: Auth.auth().currentUser?.uid ?? "x")
.getDocuments { (querySnapshot, err) in
if err != nil {
print("Failed")
return
}
let userdocid = querySnapshot!.documents[0].documentID
db.collection("users").document(userdocid).setData(["koordinaten" : selectedYearPicker])
}
I'm a beginner, and I'm while working on this, I noticed that the picker view isn't sorted
Obviously Chinese does not come after Turkish, so how do I sort it up? I've been looking at my code for hours and can't seem to figure out how to get it sorted. Here's my complete code.
Thanks
import AVFoundation
import UIKit
class SettingsView: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet var pickerView: UIPickerView!
var voicesArray: [String] = []
let speechVoices = AVSpeechSynthesisVoice.speechVoices()
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate = self
pickerView.dataSource = self
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return speechVoices.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let language = Locale.current.localizedString(forLanguageCode: speechVoices[row].language)!
let languageCode = speechVoices[row].language
var regionCode:String = ""
for region in Locale.isoRegionCodes {
// Test if provided region codes has voices or not
if languageCode.contains(region) {
regionCode = region
}
}
let country = Locale.current.localizedString(forRegionCode: String(regionCode))
return "\(language) (\(country ?? ""))"
}
#IBAction func done(_ sender: UIButton) {
dismiss(animated: true, completion: nil)
}
}
Chinese (zh) definitely comes after Turkey (tr), so these appear already sorted by region code. If you want to sort by something else (I assume their display name in the locale language), then you can sort them when you set up your list of elements for the picker. For example:
let speechVoices = AVSpeechSynthesisVoice.speechVoices().sorted(by: {
Locale.current.localizedString(forLanguageCode: $0.language)! < Locale.current.localizedString(forLanguageCode: $1.language)!
})
CODE HAS BEEN UPDATED AND IS WORKING AS EXPECTED
I have a View Controller with a text field and a PickerView. I want to display the data i have stored in Firebase inside the PickerView. I'm able to retrieve and print the data from Firebase but I can't find a way to display it inside the PickerView. Here is my code:
import UIKit
import Firebase
class pickerVC: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
#IBOutlet weak var labelTxt: UITextField!
#IBOutlet weak var infoPickerViewer: UIPickerView!
var dbRef: CollectionReference!
var pickerView: UIPickerView?
var itemsClass = [ItemInfo]()
override func viewDidLoad() {
super.viewDidLoad()
let pickerView = UIPickerView()
infoPickerViewer.delegate = self
infoPickerViewer.dataSource = self
dbRef = Firestore.firestore().collection(ITEMS_REF)
labelTxt.inputView = pickerView
labelTxt.delegate = self
self.infoPickerViewer = pickerView
self.infoPickerViewer?.delegate = self
self.infoPickerViewer?.dataSource = self
self.infoPickerViewer.reloadAllComponents()
getItems()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func textFieldDidBeginEditing(_ textField: UITextField) {
labelTxt = textField
}
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
self.pickerView?.reloadAllComponents()
return true
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if labelTxt.isFirstResponder {
return self.itemsClass.count
}
return 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if labelTxt.isFirstResponder {
return itemsClass[row].itemName
}
return nil
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if labelTxt.isFirstResponder {
let item = itemsClass[row].itemName
labelTxt.text = item
}
}
func getItems() {
dbRef.getDocuments { (snapshot, error) in
if let err = error {
debugPrint("error fetching docs: \(err)")
} else {
self.infoPickerViewer.reloadAllComponents()
let snap = snapshot
for document in snap!.documents {
let data = document.data()
let itemCode = data[ITEMS_CODE] as? String ?? ""
let itemName = data[ITEMS_NAME] as? String ?? ""
let t = ItemInfo(itemCode: itemCode, itemName: itemName)
self.itemsClass.append(t)
print("ITEMS_CODE", itemCode as Any)
print("ITEMS_NAME", itemName as Any)
}
}
}
}
}
The Firebase DB is structured as follow:
collection/AutoID/itemCode: "item1"
itemName: "item2"
collection/AutoID/itemCode: "item3"
itemName: "item4"
I only need to display the itemName inside the PickerView, the itemCode I'm going to use it to run a query depending on the selection in the PickerView.
Any help with this is greatly appreciated.
I'm still beginner in iOS development. I'm using Alamofire 4 and SwiftyJSON in order to fetch the data. When I debug, I noticed that its execute return country_list first, and then only go to Alamofire body. I have do some search but still not found the answer.
Model
import UIKit
import SwiftyJSON
import Alamofire
class CountryList {
var ReturnOK: String?
var Countryid: String?
var Countryname: String?
init(ReturnOK: String, Countryid: String, Countryname: String) {
self.ReturnOK = ReturnOK
self.Countryid = Countryid
self.Countryname = Countryname
}
/*
* Fetch the country list
*/
class func fetchCountryList() -> [CountryList] {
var country_list = [CountryList]()
// Add parameters
let param: [String: String] = [
Constants.LIST_COUNTRY.strAppID: Constants.OTHERS.temp_strAppID
]
Alamofire.request(Constants.LIST_COUNTRY.URL, parameters:param, encoding: URLEncoding.default).responseJSON { (response) in
switch response.result {
case .success(let value):
let json = JSON(value)
for (_, subJson):(String, JSON) in json {
let item = CountryList(
ReturnOK: subJson["ReturnOK"].stringValue,
Countryid: subJson["Countryid"].stringValue,
Countryname: subJson["Countryname"].stringValue)
country_list.append(item)
}
case .failure(let error):
print(error)
}
}
return country_list
}
}
ViewController
class CreateAccountViewController: UIViewController, UITextViewDelegate, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
#IBOutlet weak var tf_country: UITextField!
#IBOutlet weak var picker_country: UIPickerView!
var countryL: [CountryList]?
override func viewDidLoad() {
super.viewDidLoad()
// Get the country list
countryL = CountryList.fetchCountryList()
print(countryL)
}
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.textColor == UIColor.lightGray {
textView.text = nil
textView.textColor = UIColor.black
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.text = "Address"
textView.textColor = UIColor.lightGray
}
}
// Sets number of columns in picker view
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
// Sets the number of rows in the picker view
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if let countryL = countryL {
return countryL.count
} else {
return 0
}
}
// This function sets the text of the picker view to the content of the "salutations" array
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let titleRow = (countryL?[row] as? String)!
return titleRow
}
// When user selects an option, this function will set the text of the text field to reflect
// the selected option.
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (countryL?.count)! > 0 && (countryL?.count)! >= 0 {
self.tf_country.text = self.countryL?[row] as! String
self.picker_country.isHidden = true
}
}
func textFieldDidBeginEditing(_ textField: UITextField) {
// When select th texfield, begin editing
if (textField == self.tf_country) {
self.picker_country.isHidden = false
self.view.endEditing(true)
}
}
}
On Model I can see data is append. But when I print, it was nil.
Any help is really appreciated.
you should create a function with Completion Handler
idea here is that your Alamofire function is asynchronous, which means that, when you call return country_list, Alamofire request is not yet finished.
you should create a function with handler like
class func fetchCountries(handler: #escaping ([CountryList]) -> Void)) {
//alamofire request here
...
case .success(let value):
let json = JSON(value)
for (_, subJson):(String, JSON) in json {
let item = CountryList(
ReturnOK: subJson["ReturnOK"].stringValue,
Countryid: subJson["Countryid"].stringValue,
Countryname: subJson["Countryname"].stringValue)
country_list.append(item)
}
handler(countryList) //this return countryList from this functions
}
and inside your UIViewController it will look like
override func viewDidLoad() {
super.viewDidLoad()
// Get the country list
CountryList.fetchCountryList { [weak self] countryList in
guard let `self` = self else { //this here to avoid reference cycle
return
}
self.countryL = countryList
//update your UI here
print(countryL)
}
}
I have a problem in returning the value from a picker and comparing it to the value of an attribute. Basically, i have a Floor entity which has a attribute "floorNumber". From the picker I need to get the floor number and match it to the correct entity object so I can start assigning rooms to individual floors. I have implemented the delegate and the data source for the picker and looked at other questions on this site but I'm getting a bit confused.
Please have look at my implementation and please tell me what am I doing wrong. I have an optional "pickedFloor" which is nil even though it is being set and if I try to unwrap it it will crash it. Thank you for your help
class SetNumberOfRoomsPerFloor: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
//MARK: - Properties
#IBOutlet private weak var floorPicker: UIPickerView!
#IBOutlet private weak var numberOfRoomsPerFloor: UITextField!
private var managedObjectContext: NSManagedObjectContext!
internal var floorValue: Int16?
private var convertedFloorValues = [String]()
private var storedFloors = [Floors]()
private var pickedFloor: Int16?
private var roomNumberValue: Int16 {
get {
return Int16(numberOfRoomsPerFloor.text!)!
}
}
override func viewDidLoad() {
super.viewDidLoad()
managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
floorPicker.delegate = self
floorPicker.dataSource = self
loadFloorData()
spinnerItems()
}
#IBAction func setTheFloors(_ sender: UIButton) {
if storedFloors.count > 0 {
if storedFloors.first?.floorNumber == pickedFloor {
storedFloors.first?.numberOfRooms = roomNumberValue
print("\(storedFloors.first?.floorNumber) + \(storedFloors.first?.numberOfRooms)")
}
}
}
#IBAction func nextStep(_ sender: UIButton) {}
private func loadFloorData() {
let floorRequest: NSFetchRequest<Floors> = Floors.fetchRequest()
do {
storedFloors = try managedObjectContext.fetch(floorRequest)
} catch {
print("could not load data from core \(error.localizedDescription)")
}
}
private func spinnerItems() {
for i in 0...floorValue! - 1 {
convertedFloorValues.append(String(i))
}
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return convertedFloorValues.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return convertedFloorValues[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let selection = Int16(convertedFloorValues[row]) // not sure I have to do this part.
pickedFloor = selection
}
}
Inside this function, you should do this
private func spinnerItems() {
for i in 0...floorValue! - 1 {
convertedFloorValues.append(String(i))
}
if convertedFloorValues.count >= 1 {
pickedFloor = Int16(convertedFloorValues[0])
}
}
Like I said in the comments, didSelectRow never gets called if you don't actually move the picker view.
If the user hasn't selected anything in pickerview then pickedFloor will be nil.Try this.
#IBAction func setTheFloors(_ sender: UIButton) {
if storedFloors.count > 0 {
if storedFloors.first?.floorNumber == convertedFloorValues[floorPicker.selectedRow(inComponent: 0)] {
storedFloors.first?.numberOfRooms = roomNumberValue
print("\(storedFloors.first?.floorNumber) + \(storedFloors.first?.numberOfRooms)")
}
}
}