ScrollView, TextField and pickerview trouble - swift

My problem is that when I run the project and click the first textfield ( the others are empty for now ) the app crashes with this error :
Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason: 'child view controller:<UICompatibilityInputViewController: 0x12dd4c600> should have parent view controller:<Sai_Service.ServiceAppointment: 0x12dd151a0> but requested parent is:<UIInputWindowController: 0x12e00b600>'.
This is my code:
import UIKit
class ServiceAppointment: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var ScrollView: UIScrollView!
#IBOutlet weak var pickerView: UIPickerView!
#IBOutlet weak var StateField: UITextField!
#IBOutlet weak var CityField: UITextField!
#IBOutlet weak var VehRegNumberField: UITextField!
#IBOutlet weak var LocationField: UITextField!
#IBOutlet weak var CurrentKmsField: UITextField!
#IBOutlet weak var apptDateFIeld: UITextField!
#IBOutlet weak var apptTypeField: UITextField!
#IBOutlet weak var pickupField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
ScrollView.contentSize.height = 1000
pickerView.hidden = true;
StateField.text = States[0]
self.pickerView.dataSource = self;
self.pickerView.delegate = self;
self.StateField.inputView = pickerView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
var States = ["Italy","United States","UK","France"]
//MARK: - Delegates and data sources
//MARK: Data Sources
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return States.count
}
//MARK: Delegates
func pickerView2(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return States[row]
}
func pickerView3(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
StateField.text = States[row]
pickerView.hidden = true;
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
pickerView.hidden = false
return false
}
}
I think it's a problem of multiple view, so I wrote in the viewDidLoad:
self.StateField.removeFromSuperView()
but then all the ScrollViews disappeared obviously.
How I can make this work so that when I press the textfield, the pickerview appears?

Related

How selectRow of PickerView can affect on Button enabled?

I have UIPickerView and button. I want if I choose raw number 0 then button is not enabled and vice versa. I have this construction in my code:
import UIKit
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
...
#IBOutlet weak var buttonOutlet: UIButton!
#IBOutlet weak var firstPicker: UIPickerView!
#IBOutlet weak var secondPicker: UIPickerView!
let firstData = ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10"]
let secondData = ["00", "10", "20", "30", "40", "50"]
#IBOutlet weak var firstLabel: UILabel!
#IBOutlet weak var secondLabel: UILabel!
var first: Int!
var second: Int!
var firstRaw = 1
var secondRaw = 0
...
override func viewDidLoad() {
super.viewDidLoad()
self.firstPicker.delegate = self
self.firstPicker.dataSource = self
self.secondPicker.delegate = self
self.secondPicker.dataSource = self
firstPicker.selectRow(firstRaw, inComponent: 0, animated: true)
secondPicker.selectRow(firstRaw, inComponent: 0, animated: true)
if (self.firstRaw == 0) && (self.secondRaw == 0) {
self.buttonOutlet.isEnabled = false
} else {
self.buttonOutlet.isEnabled = true
}
...
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if pickerView == firstPicker {
...
} else {
...
}
Why this construction doesn't work?
To detect when a value is selected you must implement the UIPickerViewDelegate, also implement didSelectRow method of picker view. I'm assuming that you already populate your picker view data.
class ViewController : UIViewController, UIPickerViewDelegate {
#IBOutlet weak var buttonOutlet: UIButton!
#IBOutlet weak var firstPicker: UIPickerView!
var firstRaw = 1
...
override func viewDidLoad() {
super.viewDidLoad()
self.firstPicker.delegate = self
...
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent component: Int){
if self.firstRaw == 0 {
self.buttonOutlet.isEnabled = false
} else {
self.buttonOutlet.isEnabled = true
}
}
}

Can't save data from UIPickerView

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.

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]
}

segue to another view controller

I've been trying to segue some labels across to another view controller but i can't seem to work it out.
my first view controller:
import UIKit
class firstViewController: UIViewController,UITextFieldDelegate {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label3: UILabel!
#IBOutlet weak var label4: UILabel!
#IBOutlet weak var label5: UILabel!
#IBOutlet weak var label6: UILabel!
var pickerLabels: [String!] {
return [label1.text,label2.text,label3.text,label4.text,label5.text,label6.text]
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let controller = segue.destinationViewController as thirdViewController
controller.vc2Labels = pickerLabels //pickerLabels shows error
}
}
the labels in here are what I'm trying to segue but "pickerLabels" keeps coming up with an error
my second view controller:
import UIKit
class secondViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var vc2Labels: [String]!
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int{
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component:Int) -> Int{
return vc2Labels.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String!{
return vc2Labels[row]
}
I think I know your problem. You seem to be passing in an array of String into a string object.
Maybe you can alter your second view controller's variable to be:
var vc2Labels: [String]!
but I wouldn't recommend using implicit unwrapping of optional, since it allows a passing in of nil. You can declare an empty array like this.
var vc2Labels = [String]()
Hope this helps. More context would be helpful.