Can't save data from UIPickerView - swift

I tried to program a sign up view controller and use a UIPickerView for country choice. The issue is that when I tried to pass the picker country to Parse to save the input, Xcode give me an error. Why Xcode can't allow me to use the selected data to Parse? The error is in the last line.
Any help guys?
#IBOutlet var usernameTextField: UITextField!
#IBOutlet var fullnameTextField: UITextField!
#IBOutlet var emailTextField: UITextField!
#IBOutlet var passwordTextField: UITextField!
#IBOutlet var phonenumberTextField: UITextField!
#IBOutlet var countryPicker: UIPickerView!
let countryData: [String] = ["Saudi Arabia", "Turkey"]
#available(iOS 2.0, *)
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return countryData.count
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let countrySelect = countryData[row]
print(countrySelect)
}
override func viewDidLoad() {
super.viewDidLoad()
countryPicker.dataSource = self
countryPicker.delegate = self
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func signUpAction(sender: AnyObject) {
// Declare user object
let newUser = PFUser()
let fullName = fullnameTextField.text!
let username = usernameTextField.text!
let email:String = emailTextField.text!
let password:String = passwordTextField.text!
let phoneNumber:Int? = Int(phonenumberTextField.text!)
// Passing arguments
newUser.username = username
newUser["fullName"] = fullName
newUser.email = email
newUser.password = password
newUser["phoneNumber"] = phoneNumber! as Int
newUser["country"] = countryData [row]

Based on your comment that the error is "unresolved identifier row":
You are never declaring a variable named row, yet you're using it. You can either replace the use of this undefined variable with the correct array index that will give you the country from the countryData variable OR you make sure that row is actually declared and accessible in your function.

Related

UILabel value is not changing based on the pickerView selection

I want to choose and display the correct dataset from Firebase, based on the pickerView selection.
The main problem - the values of the UILabels are not changing.
The second thing I would like to note, that the pickerView does not disappear after I click on one of the values in it.
import UIKit
import Firebase
class ViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet weak var priceView: UILabel!
#IBOutlet weak var dayView: UILabel!
#IBOutlet weak var monthView: UILabel!
#IBOutlet weak var personPicker: UITextField!
var ref: DatabaseReference?
var databaseHandle: DatabaseHandle?
var postData = [String]()
var person : String = "jack"
let people = ["jack", "jenny", "don"]
override func viewDidLoad() {
super.viewDidLoad()
let pickerView = UIPickerView()
personPicker.delegate = self
personPicker.inputView = pickerView
ref = Database.database().reference()
ref?.child("xf").child(person).child("price").observe(.value, with: { (snapshot) in
if let i = snapshot.value as? Double
self.priceView.text = "\(i)"
self.priceView.reloadInputViews()
}
})
ref?.child("xf").child(person).child("day").observe(.value, with: { (snapshot) in
if let i = snapshot.value as? String {
self.dayView.text = "\(i)"
self.dayView.reloadInputViews()
}
})
ref?.child("xf").child(person).child("month").observe(.value, with: { (snapshot) in
if let i = snapshot.value as? String {
self.monthView.text = "\(i)"
self.monthView.reloadInputViews()
}
})
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return people.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return people[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
personPicker.text = people[row]
person = people[row]
}
}
For the first issue, I tried adding the 'person = people[row]' but the values in the UILabes do not change
For the issue with the pickerView removal, I tried adding 'pickerView.isHidden = true', but it only removes the values, not the card
Xcode Version 12.3

implementing Replace and Insert Buttons in Xcode/Swift

I am new to xCode and confused about implementing the following two things to the replace button and insert button. Can someone please helpWhen you press the
“replace” button, the item selected in the picker should be replaced by the contents of the text field (blank if
nothing in the text field). When you press “insert”, the contents of the text field should be added to the data for
the picker, after the item currently selected, and the new, added, item should be shown in the picker as the
selected item (so the previously selected item would be immediately above it on the picker’s display at that
point).
class ViewController: UIViewController {
#IBOutlet weak var countryTextField: UITextField!
#IBOutlet weak var selectButton: UIButton!
#IBOutlet weak var replaceButton: UIButton!
#IBOutlet weak var insertButton: UIButton!
let countries = ["USA", "MEXICO", "CANADA"]
var pickerView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
pickerView.delegate = self
pickerView.dataSource = self
countryTextField.inputView = pickerView
countryTextField.textAlignment = .center
}
}
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return countries.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return countries[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
countryTextField.text = countries[row]
countryTextField.resignFirstResponder()
}
}
Create #IBAction for your Buttons from xib and add conditions accordingly. It will look like these-
#IBAction func insertAction(sender: UIButton){
// write code for insert
}
#IBAction func replaceAction(sender: UIButton){
// write code for replace
}

How to add elements to a realm database

I am working on a simple app that catalogues information. Right now I am just trying to collect information and then add it to a realm database. Unfortunately I cannot figure it out and no matter what method I try (based on tutorials and the Realm website) I get the error "Use of unresolved identifier 'realm'.
This is the code based on the command button executing the command.
#IBAction func Submit(_ sender: Any) {
let myList = WineList()
myList.vinyard = Vinyard.text
myList.type = typeField.text
myList.name = Name.text
myList.grape = Grape.text
myList.year = Year.text
myList.price = Price.text
myList.rating = rateField.text
myList.purchased = purch
myList.notes = Notes.text
//from realm website example
try! realm.write{
realm.add(myList)
}
//from tutorials
//realm.beginWrite()
//realm.add(myList)
//try realm.commitWrite()
}
Can anyone please advise me on what I am doing wrong? I will post all of my code below.
import UIKit
import RealmSwift
class RankViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var purch = ""
#IBOutlet weak var typeField : UITextField!
#IBOutlet weak var rateField : UITextField!
#IBOutlet weak var Vinyard: UITextField!
#IBOutlet weak var Name: UITextField!
#IBOutlet weak var Grape: UITextField!
#IBOutlet weak var Year: UITextField!
#IBOutlet weak var Price: UITextField!
#IBOutlet weak var Notes: UITextField!
#IBAction func Purchased(_ sender: UISwitch) {
if (sender.isOn == true){
purch = "Yes"
}
else {
purch = "No"
}
}
let wineTypes = ["Red","White","Rose","Sparkling","Ice - Red","Ice - White", "Port","Fruit","Other"]
let wineRate = ["Hurray", "Meh", "Boo"]
var typeView = UIPickerView()
var rateView = UIPickerView()
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
print (Realm.Configuration.defaultConfiguration.fileURL)
typeView.delegate = self
typeView.dataSource = self
rateView.delegate = self
rateView.dataSource = self
Vinyard.delegate = self
Name.delegate = self
Grape.delegate = self
Year.delegate = self
Price.delegate = self
Notes.delegate = self
typeField.inputView = typeView
rateField.inputView = rateView
}
public func numberOfComponents(in pickerView: UIPickerView) -> Int {
if pickerView == typeView {
// Returns for typeView
return 1
}
else if pickerView == rateView {
// Returns for rateView
return 1
}
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView == typeView {
// Returns for typeView
return wineTypes.count
}
else if pickerView == rateView {
// Returns for rateView
return wineRate.count
}
return wineRate.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if pickerView == typeView {
// Returns for typeView
return wineTypes[row]
}
else if pickerView == rateView {
// Returns for rateView
return wineRate[row]
}
return wineRate[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == typeView {
// Do stuff for typeView
typeField.text = wineTypes[row]
typeField.resignFirstResponder()
}
else if pickerView == rateView {
// Do stuff for rateView
typeField.text = wineRate[row]
typeField.resignFirstResponder()
}
}
#IBAction func Submit(_ sender: Any) {
let myList = WineList()
myList.vinyard = Vinyard.text
myList.type = typeField.text
myList.name = Name.text
myList.grape = Grape.text
myList.year = Year.text
myList.price = Price.text
myList.rating = rateField.text
myList.purchased = purch
myList.notes = Notes.text
//from realm website example
try! realm.write{
realm.add(myList)
}
//from tutorials
//realm.beginWrite()
//realm.add(myList)
//try realm.commitWrite()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
Year.resignFirstResponder()
Price.resignFirstResponder()
}
}
extension RankViewController : UITextFieldDelegate{
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
Separate file
import Foundation
import RealmSwift
class WineList: Object {
#objc dynamic var vinyard: String?
#objc dynamic var name: String?
#objc dynamic var grape: String?
#objc dynamic var year: String?
#objc dynamic var price: String?
#objc dynamic var notes: String?
#objc dynamic var type: String?
#objc dynamic var rating: String?
#objc dynamic var purchased: String?
}
Variables only exist with the function or class they are created. So take these two functions
func getData() {
let realm = Realm()
let results = realm.objects...
}
and
func printData() {
print(results) //this won't work
}
as you can see, the var 'realm' is instantiated in getData so that var is only available within that function and would not be available within the printData function.
In your case you've instantiated the realm var within viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
let realm = try! Realm()
therefore it will only be available within the viewDidLoad function.
To correct your issue, you need to instantiate realm within the function where you're trying to use it
#IBAction func Submit(_ sender: Any) {
let myList = WineList()
...
let realm = try! Realm()
try! realm.write{
realm.add(myList)
}
to expand on that a bit. Take your RankViewController class
class RankViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var purch = ""
See the 'purch' var? That's called a 'class var' and because it's defined at a high level within the class, it would be available throughout the class.
func printData() {
print(self.purch) //this will work
}
note that I preceded purch with self. when I referenced it. To me, that's a good indicator it's a class var and makes the code more readable. However, it's not required.

EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode=0x0)

I'm creating a temperature converter. When I run the application; enter a temperature, select which conversion and click convert. An error comes up.
THE ERROR IS: EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP, subcode=0x0)
This is my code for ViewController:
import UIKit
class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
#IBOutlet weak var orginalValue: UITextField!
#IBOutlet weak var convertFrom: UIPickerView!
let pickerData = ["Celsius", "Fahrenheit"]
override func viewDidLoad() {
super.viewDidLoad()
convertFrom.dataSource = self
convertFrom.delegate = self
}
#IBOutlet weak var labelConvertFrom: UILabel!
#IBOutlet weak var convertTo: UIPickerView!
#IBOutlet weak var labelConverTo: UILabel!
#IBOutlet weak var answer: UILabel!
#IBAction func convertButton(sender: AnyObject) {
let a = Double(orginalValue.text!)
let tempConvertM = TempConvert(temp: a!)
answer.text = String(tempConvertM.convert())
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return pickerData.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return pickerData[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
labelConvertFrom.text = pickerData[row]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here is where I'm getting the error.
TempConverterModel.swift
import Foundation
extension ViewController{
class TempConvert{
var temp:Double
var view = ViewController()
init (temp:Double){
self.temp = temp
}
func convert()->Double{
if(view.labelConvertFrom.text == "Celsius"){ -->ERROR IS HIGHLIGHTED HERE <--
view.labelConverTo.text = "Fahrenheit"
return (temp-32)/1.8000; //fahrenheit formula
}
else{
view.labelConverTo.text = "Celsius"
return (temp*1.8000)+32; //celsius formula
}
}
}
}
I don't know what I'm doing wrong. I want to check the text in labelConvertFrom and check if it equals to "Celsius". IF it does not then return answer.
I would really appreciate anyones help. Thank you!
As par pointed out, you should be removing the enclosing extension ViewController { } and have your TempConvert as a separate class.
Also, instead of trying to access the ViewController's instance variables in TempConvert, you should be doing the comparisons in your convertButton() method in ViewController class itself and call the appropriate conversion method in TempConvert class.
A better approach is to have a stored property for "Celsius" and a computed property for "Fahrenheit" within your ViewController class. You can refer this link for Properties in Swift language
The problem broadly stems from this line in class TempConvert:
var view = ViewController()
Here you are initializing an empty view controller. The outlets you've defined such as labelConvertFrom are not hooked up to anything, so when you try to deference them here:
view.labelConvertFrom.*text
you crash (specifically, you crash where I put the * character). The reason you crash is because at that point, labelConvertFrom is nil.
To get this to work right, you'll need to initialize the ViewController using the initWithNibName:bundle: method, passing the correct nib filename and bundle id (which is probably just NSBundle.mainBundle()).
Doing this will allow your outlets to be hooked up properly and then they won't be nil when you try to use them.

Random name selector using a picker view with swift

I'm trying populate a pickerview using the text from labels.
I've tried searching online and in books for how to do this but no luck yet.
what i have so far shows no errors but still won't run
thanks
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate,UIPickerViewDataSource,UITextFieldDelegate{
#IBOutlet weak var label3: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var textField2: UITextField!
#IBOutlet weak var textField3: UITextField!
#IBAction func button(sender: UIButton) {
label.text = textField.text
label2.text = textField2.text
label3.text = textField3.text
self.textField.resignFirstResponder()
self.textField2.resignFirstResponder()
self.textField3.resignFirstResponder()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
return false
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
var pickerLabels: [UILabel!] {
return [label,label2,label3]
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int{
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component:Int) -> Int{
return pickerLabels.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> NSArray{
return pickerLabels
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You are sending UILabels to your array.
I believe what you are trying to achieve needs you to get the text from the UILabels and also to format the array as [String] on your computed property..
var pickerLabels: [String!] {
return [label.text, label2.text, label3.text]
}