Swift app crashing without any errors? - swift

I have an app in Swift. I have a view controller:
//
// ViewController.swift
// SwiftUIPickerFormatted
//
// Created by Codepixl
// Copyright (c) 2014
//
import UIKit
class FirstViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate,UIAlertViewDelegate {
#IBOutlet weak var chapterPicker: UIPickerView!
let chapterData = [1,2,3,4,5,6,7,8,9,10,11,12,13]
let lessonData = [1,2,3,4,5,6,7,8,9,10]
let classData = ["Pre Algebra","Algebra 1"]
var data = ["ade","01","01"]
override func viewDidLoad() {
super.viewDidLoad()
if(UIApplication.sharedApplication().canOpenURL(NSURL(string:"puffin://")!) == true){
println("Can open Puffin links")
}else{
showPuffinAlert()
}
chapterPicker.delegate = self
chapterPicker.dataSource = self
}
//MARK: - Delegates and datasources
//MARK: Data Sources
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 3
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if(component == 0){
return classData.count
}else if(component == 1){
return chapterData.count
}else if(component == 2){
return lessonData.count
}
return 1
}
//MARK: Delegates
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
if(component == 0){
return classData[row]
}else if(component == 1){
return "Chapter " + String(chapterData[row])
}else if(component == 2){
return "Lesson " + String(lessonData[row])
}
return "Error!"
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if(component == 0){
if(row == 0){
data[0] = "ade"
}else if(row == 1){
data[0] = "ate"
}
}else if(component == 1 || component == 2){
if(row+1 < 10){
data[component] = "0"+String(row+1)
}else{
data[component] = String(row+1)
}
}
println("puffin://www.phschool.com/webcodes10/index.cfm?wcprefix=\(data[0])&wcsuffix=\(data[1])\(data[2])&area=view")
}
func showPuffinAlert(){
var createAccountErrorAlert: UIAlertView = UIAlertView()
createAccountErrorAlert.delegate = self
createAccountErrorAlert.title = "Oops!"
createAccountErrorAlert.message = "It seems you do not have the Puffin web browser installed, which is required for this app to work. You can go ahead, but be aware the video and textbook links will not work."
createAccountErrorAlert.addButtonWithTitle("I understand- Proceed.")
createAccountErrorAlert.addButtonWithTitle("I'll download Puffin for free.")
createAccountErrorAlert.show()
}
func alertView(View: UIAlertView!, clickedButtonAtIndex buttonIndex: Int){
switch buttonIndex{
case 0:
NSLog("Proceed");
break
case 1:
NSLog("DL");
UIApplication.sharedApplication().openURL(NSURL(string: "https://itunes.apple.com/us/app/puffin-academy/id716707933?mt=8#")!)
break
default:
NSLog("Default");
break
//Some code here..
}
}
#IBAction func GoVideo(sender: AnyObject) {
UIApplication.sharedApplication().openURL(NSURL(string:"puffin://www.phschool.com/webcodes10/index.cfm?wcprefix=\(data[0])&wcsuffix=\(data[1])\(data[2])&area=view")!)
}
}
And all works fine until I hit the "I understand-Proceed" or "I'll download Puffin for free" or the GoVideo button- it crashes with no error. I am completely stumped here as to what is happening...
EDIT: I have also cleared my build folder and manually deleted everything in it as well as adding a println in my app delegate and view controllers to make sure they have updated, and they have. Also the Simulator has been cleared.

There's probably a corrupted file in your Xcode project. Just make a new project and try the code there.

Related

How to add a special character in a UIPicker view of integers

Still Learning swift
What Im trying to do is add a "°C" and "°F"
after an integer, I have a created and array of ints and gave them a specific range
that should be in the pickerView, I got the values to display Im just struggling with how I could get that "special char " to display after the integer
I was thinking of maybe creating a for loop and load in the the values like that and append the "°C" and "°F" using the unicode scalar.
I was wondering if anyone has any recommendations of how i could get this done ?
class tempConversionTabViewController: UIViewController, UIPickerViewDataSource, UIPickerViewDelegate {
var celsius: [Int] = []
var fahrenheitTemps: [Int] = []
override func viewDidLoad() {
super.viewDidLoad()
fahrenheitTemps += -129...134
celsius += -90...57
// for fahrenheitTemps in -129...134{
// tempPicker.append
//}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
switch
segmentControl.selectedSegmentIndex{
case 0:
return fahrenheitTemps.count
default:
return celsius.count
}
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int , forComponent component: Int) -> String?{
switch segmentControl.selectedSegmentIndex {
case 0:
var selected = fahrenheitTemps[tempPicker.selectedRow(inComponent: 0)]
selected = (selected - 32) * 5/9
convertedLabel.text = String("\(selected) \u{2103}")
let myString = fahrenheitTemps.map { String($0)}
return myString[row]
default:
var selected = celsius[tempPicker.selectedRow(inComponent: 0)]
selected = (selected * 9/5) + 32
convertedLabel.text = String("\(selected) \u{2109}")
let myString = celsius.map { String($0)}
return myString[row]
}
}
Image of how I want it to display
Just use string concatenation to add the character:
Change:
return myString[row]
to:
return myString[row] + "\u{2109}"

Create a warning based on UIPickerViewSelection

So here is what I am trying to do.
I am working on an app that allows the company I work for to see what account number they should use when making a purchase. There are certain locations where the costs should be split to different accounts based on location, but they are only for a certain few. I would like to issue a warning in the form of a popup, which I already have coded. My thought process is that I can use if/else statements to issue what I need, but I am unsure as to how to word it. It would supply a regular account number if the accounts need not be split, but then a warning statement if it did. The code is below. My problem is under the didSelectRow.
What's not actually shown is the PopUpVC I am using and the full list of array data because it's long.
Much thanks to this website as it has really helped me code my first project!
let account: [Account] = [Account(number: 0, description: "SELECT")]
//there is actually more data here but I am taking it out so it's shorter
let tasks: [Task] = [Task(number: 0, description: "SELECT")]
//there is actually more data here but I am taking it out so it's shorter
let locations: [Location] = [Location(number: 0, description: "SELECT")]
//there is actually more data here but I am taking it out so it's shorter
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 3
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == accountsComponent {
return account.count
} else if component == tasksComponent {
return tasks.count
} else if component == locationsComponent {
return locations.count
}
return 0
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == accountsComponent {
return account[row].description
} else if component == tasksComponent {
return tasks[row].description
} else if component == locationsComponent {
return locations[row].description
}
return nil
}
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
if component == accountsComponent {
let label = (view as? UILabel) ?? UILabel()
label.font = label.font.withSize(12)
label.textAlignment = .center
label.text = account[row].description
return label
}
if component == tasksComponent {
let label = (view as? UILabel) ?? UILabel()
label.font = label.font.withSize(12)
label.textAlignment = .center
label.text = tasks[row].description
return label
}
if component == locationsComponent {
let label = (view as? UILabel) ?? UILabel()
label.font = label.font.withSize(12)
label.textAlignment = .center
label.text = locations[row].description
return label
} else {
let label = (view as? UILabel) ?? UILabel()
label.font = label.font.withSize(10)
label.textAlignment = .center
label.text = account[row].description
return label
}
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
pickerView.reloadAllComponents()
let selectedAccount = pickerView.selectedRow(inComponent: 0)
let selectedTask = pickerView.selectedRow(inComponent: 1)
let selectedLocation = pickerView.selectedRow(inComponent: 2)
let ACCOUNTS = account[selectedAccount].description
let TASKS = tasks[selectedTask].description
let LOCATION = locations[selectedLocation].description
let ACCOUNTSNUMBER = account[selectedAccount].number
let TASKSNUMBER = tasks[selectedTask].number
let LOCATIONNUMBER = locations[selectedLocation].number
if pickerView.selectedRow(inComponent: 2) = 10 //this is what I am unsure of how to do {
textViewInput = "WARNING - this should be split"
}
else {
textViewInput = "\(ACCOUNTSNUMBER) \(TASKSNUMBER) \(LOCATIONNUMBER)"
}
I prefer switch statements over a long series of if-else if-else statements. I would personally do something like this:
switch pickerView.selectedRow(inComponent: 2) {
case 10, 11, 12:
present(popUpVc, animated: true)
default:
textViewInput = "\(ACCOUNTSNUMBER) \(TASKSNUMBER) \(LOCATIONNUMBER)"
}
In this case, you would replace what I put as 10, 11, 12 as whatever rows you determine that need to have the accounts split. I'm also assuming here that PopUpVC is a UIAlertController that you are using to display the warning to the user.

How to use NSUserDefault with PickerView in Swift?

I made some Labels that change using PickerView. But when I change the Label and if I run my app again, it doesn't save to selected one. So I have to use NSUserDefault but I don't know how to use it in right way.
This is my code:
var selectedFood = 0
class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet var foodLabel: UILabel!
#IBOutlet var labelTwo: UILabel!
#IBOutlet var labelThree: UILabel!
#IBOutlet weak var foodPicker: UIPickerView!
var food = ["Bread", "Pizza", "Pasta", "Hot Dog", "Burger"]
#IBAction func submitLanguageButton(sender: AnyObject) {
if (selectedFood == 0) {
foodLabel.text = "Bread"
labelTwo.text = "Bread is a staple food prepared from a dough of flour and water..."
labelThree.text = "Bread is one of the oldest prepared foods..." // I used random information just as sample
}
else if (selectedFood == 1) {
foodLabel.text = "Pizza"
labelTwo.text = "Here will be more informations about Pizza"
labelThree.text = "A fact about Pizza" // I used random information just as sample
}
else if (selectedFood == 2) {
foodLabel.text = "Pasta"
labelTwo.text = "Here will be more informations about Pasta"
labelThree.text = "A fact about Pasta" // I used random information just as sample
}
else if (selectedFood == 3) {
foodLabel.text = "Hot Dog"
labelTwo.text = "Here will be more informations about Hot Dog"
labelThree.text = "A fact about Hot Dog" // I used random information just as sample
}
else if (selectedFood == 4) {
foodLabel.text = "Burger"
labelTwo.text = "Here will be more informations about Burger"
labelThree.text = "A fact about Burger" // I used random information just as sample
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
foodPicker.delegate = self
foodPicker.dataSource = self
if (selectedFood == 0) {
foodLabel.text = "Bread"
labelTwo.text = "Bread is a staple food prepared from a dough of flour and water..."
labelThree.text = "Bread is one of the oldest prepared foods..." // I used random information just as sample
}
else if (selectedFood == 1) {
foodLabel.text = "Pizza"
labelTwo.text = "Here will be more informations about Pizza"
labelThree.text = "A fact about Pizza" // I used random information just as sample
}
else if (selectedFood == 2) {
foodLabel.text = "Pasta"
labelTwo.text = "Here will be more informations about Pasta"
labelThree.text = "A fact about Pasta" // I used random information just as sample
}
else if (selectedFood == 3) {
foodLabel.text = "Hot Dog"
labelTwo.text = "Here will be more informations about Hot Dog"
labelThree.text = "A fact about Hot Dog" // I used random information just as sample
}
else if (selectedFood == 4) {
foodLabel.text = "Burger"
labelTwo.text = "Here will be more informations about Burger"
labelThree.text = "A fact about Burger" // I used random information just as sample
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return food[row]
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return food.count
}
public func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
selectedFood = row
}
}
So when I choose Pizza, whenever I run my app I want to be it Pizza, if I select another one for example Pasta, I want to be that one Pasta.
Can you please help me ?
WBMDDrugManagerErrorCodeSave the selection like so:
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
NSUserDefaults.standardUserDefaults().setInteger(row, forKey: "choosenFood")
NSUserDefaults.standardUserDefaults().synchronize()
self.setLabelsForChoice(row)
}
Retrieve the chosen selection like so:
override func viewWillAppear() {
super.viewWillAppear()
if let previousSelection:Int = NSUserDefaults.standardUserDefaults().integerForKey("choosenFood") as? Int{
self.setLabelsForChoice(previousSelection)
}
}
Create a label update method similar to this:
func setLabelsForChoice(_choice:Int){
switch _choice{
case 0:
foodLabel.text = "Bread"
labelTwo.text = "Bread is a staple food prepared from a dough of flour and water..."
labelThree.text = "Bread is one of the oldest prepared foods..."
break
case 1:
foodLabel.text = "Pizza"
labelTwo.text = "Here will be more informations about Pizza"
labelThree.text = "A fact about Pizza"
break
default:
break
}
}

Issue saving PFobjects into an array when using pickerView

i'm relatively new to Swift. I've encountered an issue when using PFQuery in pickerView.
I'm trying to implement a 2 component pickerView as demonstrated below:
Component 0: Component 1
"A": "Altivo", "Altrez"
"B": "Beverly", "Bijou"
Choosing "A" from Component 0 will show "Altivo", "Altrez" in Component 1
The values from Component 1 are queried from Parse by using the value from Component 0
Here's my code:
var condoNameList: [String] = [String]()
var condoPicker = UIPickerView()
var condoAlphabet: [String] = [String]()
private let prefixComponent = 0
private let condoNameComponent = 1
override func viewDidLoad() {
super.viewDidLoad()
condoAlphabet = ["A", "B"]
}
//Start: For condoName picker
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 2
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if component == prefixComponent{
return condoAlphabet.count
}else {
return self.condoNameList.count
}
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if component == prefixComponent {
condoNameList.removeAll()
let query = PFQuery(className: "condodirectory")
let selectedalphabet: String = condoAlphabet[row] as String!
query.whereKey("condoName", hasPrefix: selectedalphabet)
query.findObjectsInBackgroundWithBlock{
(objects:[PFObject]?, error:NSError?)->Void in
if error == nil{
for object in objects!{
//print(object)
let condoName:String = object["condoName"] as! String
self.condoNameList.append(condoName)
}
}
//print("condo Name List is \(self.condoNameList)") //Position 1
}
print("condo Name List is \(self.condoNameList)") //Position 2
condoPicker.reloadComponent(condoNameComponent)
condoPicker.selectRow(0, inComponent: condoNameComponent, animated: true)
}
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if component == prefixComponent{
return condoAlphabet[row]
}else {
return self.condoNameList[row]
}
}
The issue is at Position 1, the print function is able to print out the condoNameList but at Position 2 it prints an empty array. As a result, the list for Component 1 is not showing up in the PickerView.
Anyone knows why?
Thanks in advance for the help.
I managed to solve the problem from another thread by using the didset{} method.
var condoNameList: [String] = [] {
didSet {
self.condoNameListTemp = condoNameList
condoName.inputView = condoPicker
condoPicker.reloadAllComponents()
}
}

Return picker view to the previously selected row

In my app I allow the user to change the colour theme for the app via a picker view. In doing this, UI elements such as the bars and buttons are changed based on what the user chooses.
I am having an issue with the picker view returning to the first item when the view is closed and reopened. How can I make the picker view return to the colour that the user previously selected?
Here is the code that I currently have for the picker view:
func numberOfComponentsInPickerView(pickerView: UIPickerView!) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView!, numberOfRowsInComponent component: Int) -> Int {
return coloursArray.count
}
func pickerView(pickerView: UIPickerView!, titleForRow row: Int, forComponent component: Int) -> String! {
return coloursArray[row]
}
func pickerView(pickerView: UIPickerView!, didSelectRow row: Int, inComponent: Int) {
colourSelected = row
if colourSelected == 0 {
self.navigationController.navigationBar.barTintColor = UIColor.newBlueColor()
self.tabBarController.tabBar.selectedImageTintColor = UIColor.newBlueColor()
UINavigationBar.appearance().barTintColor = UIColor.newBlueColor()
UISegmentedControl.appearance().tintColor = UIColor.newBlueColor()
changeButton.layer.backgroundColor = (UIColor.newBlueColor()).CGColor
} else if colourSelected == 1 {
self.navigationController.navigationBar.barTintColor = UIColor.newGreenColor()
self.tabBarController.tabBar.selectedImageTintColor = UIColor.newGreenColor()
UINavigationBar.appearance().barTintColor = UIColor.newGreenColor()
UIButton.appearance().setTitleColor(UIColor.newGreenColor(), forState: UIControlState())
UISegmentedControl.appearance().tintColor = UIColor.newGreenColor()
changeButton.layer.backgroundColor = (UIColor.newGreenColor()).CGColor
} else if colourSelected == 2 {
self.navigationController.navigationBar.barTintColor = UIColor.newOrangeColor()
self.tabBarController.tabBar.selectedImageTintColor = UIColor.newOrangeColor()
UINavigationBar.appearance().barTintColor = UIColor.newOrangeColor()
UISegmentedControl.appearance().tintColor = UIColor.newOrangeColor()
changeButton.layer.backgroundColor = (UIColor.newOrangeColor()).CGColor
} else if colourSelected == 3 {
self.navigationController.navigationBar.barTintColor = UIColor.newPurpleColor()
self.tabBarController.tabBar.selectedImageTintColor = UIColor.newPurpleColor()
UINavigationBar.appearance().barTintColor = UIColor.newPurpleColor()
UISegmentedControl.appearance().tintColor = UIColor.newPurpleColor()
changeButton.layer.backgroundColor = (UIColor.newPurpleColor()).CGColor
} else if colourSelected == 4 {
self.navigationController.navigationBar.barTintColor = UIColor.newRedColor()
self.tabBarController.tabBar.selectedImageTintColor = UIColor.newRedColor()
UINavigationBar.appearance().barTintColor = UIColor.newRedColor()
UISegmentedControl.appearance().tintColor = UIColor.newRedColor()
changeButton.layer.backgroundColor = (UIColor.newRedColor()).CGColor
} else if colourSelected == 5 {
self.navigationController.navigationBar.barTintColor = UIColor.newTurquoiseColor()
self.tabBarController.tabBar.selectedImageTintColor = UIColor.newTurquoiseColor()
UINavigationBar.appearance().barTintColor = UIColor.newTurquoiseColor()
UISegmentedControl.appearance().tintColor = UIColor.newTurquoiseColor()
changeButton.layer.backgroundColor = (UIColor.newTurquoiseColor()).CGColor
}
}
Supposing you have one column ("component") in your picker:
override func viewDidLoad() {
super.viewDidLoad()
let idx = NSUserDefaults.standardUserDefaults().integerForKey("SavedIndex")
pickerView.selectRow(idx, inComponent: 0, animated: false)
}
And, of course, save to NSUserDefaults when a row has been selected.
Depending on your setup, you might have to put this into viewWillAppear().