App crashing when adding second stepper - ios

I have successfully got a step updating the values of a Text Field and now i am trying to add a second stepper but the app is now crashing.
#IBOutlet weak var propertyTypeField: UITextField!
#IBOutlet weak var insuranceTypeField: UITextField!
#IBOutlet weak var bedroomField: UITextField!
#IBOutlet weak var bathroomField: UITextField!
#IBOutlet weak var doYouOwnPropertyField: UITextField!
#IBOutlet weak var propertyYearField: UITextField!
#IBOutlet weak var bathroomStepper: UIStepper!
#IBOutlet weak var bedroomStepper: UIStepper!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor(red: 0xE1/255, green: 0xE1/255, blue: 0xE1/255, alpha: 1.0)
//Bedroom stepper setup
bedroomField.text = "\(Int(bedroomStepper.value))"
bedroomStepper.addTarget(self, action: "stepperValueDidChange:", forControlEvents: .ValueChanged)
//Bathroom stepper setup
bathroomField.text = "\(Int(bathroomStepper.value))"
bathroomStepper.addTarget(self, action: "stepperValueDidChange:", forControlEvents: .ValueChanged)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func viewTapped(sender : AnyObject) {
propertyTypeField.resignFirstResponder()
insuranceTypeField.resignFirstResponder()
bedroomField.resignFirstResponder()
bathroomField.resignFirstResponder()
doYouOwnPropertyField.resignFirstResponder()
propertyYearField.resignFirstResponder()
}
func stepperValueDidChange(stepper: UIStepper) {
let bedroomStepperMapping: [UIStepper: UITextField] = [bedroomStepper: bedroomField]
if !(bedroomField.text == ""){
bedroomStepperMapping[stepper]!.text = "\(Int(stepper.value))"}
let bathroomStepperMapping: [UIStepper: UITextField] = [bathroomStepper: bathroomField]
if !(bathroomField.text == ""){
bathroomStepperMapping[stepper]!.text = "\(Int(stepper.value))"}
}
This is the whole code i am using.
The error i am getting is
fatal error: unexpectedly found nil while unwrapping an Optional value
Hope someone can help.
Thanks

By using ! bedroomStepperMapping[stepper]!.text your telling the compiler there will be a value there. As there is not one apparently you are getting the error. Check if the value is nil before unwrapping it
To check for nil in the line you say is the issue
if !(bedroomField.text == ""){
//Ok to unwrap object
}

While if you are using the optional value first check if value exist if not then there must not b null so do it as
if let bedFeild = Int(stepper.value) {
bedroomStepperMapping[stepper].text = bedFeild
}
Now there will be no crash if the value exist then value will be assigned to it else no without any crash

func stepperValueDidChange(stepper: UIStepper) {
if bedroomStepper == stepper{
bedroomField.text = "\(Int(stepper.value))"}
if bathroomStepper == stepper{
bathroomField.text = "\(Int(stepper.value))"}
}
}

Related

How to enable IBAction once numbers are entered into a UIText Field

I am quite new to a programming and I need a help.
I am trying to build a simple calculator. In nutshell: There are two UITextField where the numbers are inserted. There is IBAction (buttonCalculate) that performs the calculation + there is another IBAction (buttonClear) that clears the data inserted into text fields. Upon starting the application both IBAction buttons are disabled. The goal is to enable the IBAction (buttonCalculate) once numbers are inserted. In case the user inserts any other character then numbers a warning message(warrningSign2) needs to appear telling the user that ony numbers are accepted.
Can somebody give a tip / hint how I should proceed?
Thanks!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Value: UITextField!
#IBOutlet weak var field1: UITextField!
#IBOutlet weak var field2: UITextField!
#IBOutlet weak var buttonClear: UIButton!
#IBOutlet weak var buttonCalculate: UIButton!
#IBOutlet weak var warrningSign: UITextField!
#IBOutlet weak var warrningSign2: UITextField!
func appLoad () {
buttonClear.isEnabled = false
buttonClear.backgroundColor = .gray
if field1.text == "" || field1.text == "" {
warrningSign.textColor = .red
butonCalculate.isEnabled = false
butonCalculate.backgroundColor = .gray}
}
override func viewDidLoad() {
super.viewDidLoad()
appLoad()
}
#IBAction func calculate(_ sender: Any) {
buttonClear.isEnabled = true
buttonClear.backgroundColor = UIColor(red: 74/255, green: 105/255, blue:187/255, alpha: 1)
Value.text = String(Float(field1.text!)! + Float(field2.text!)!)
}
#IBAction func Clear(_ sender: Any) {
Value.text = "Value"
self.field1.text = nil
self.field2.text = nil
}
}
Make UITextField(field1 and field2) Keyboard type to Number Pad or only acceptable number type.
You can catch the characters sent to a UITextField control by adding the below line:
textField.addTarget(self, action: #selector(textFieldDidChange), for: .editingChanged)
In textFieldDidChange delegate method you can get the text and validate as per your needs.
I would recommend to update the code like below,
#IBAction func calculate(_ sender: Any) {
calculateAction()
}
private func calculateAction() {
buttonClear.isEnabled = true
buttonClear.backgroundColor = UIColor(red: 74/255, green: 105/255, blue:187/255, alpha: 1)
Value.text = String(Float(field1.text!)! + Float(field2.text!)!)
}
And then call the calculateAction() in textFieldDidChange().

Found nil when unwrapping optional value in core data

I've been trying to address this issue for a few days and it seems I'm only going in circles.
I'm adding data to core data by tapping on tableView cells and then displaying the items on another tableView.
That works great, the problem is this:
When I click on the other table view rows, to be able to see the item with all the other values stored in core data, I get
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value on the showMeTheGoodiesTwo(entry: myCart) line
...Inside viewDidLoad. But I do not know why that's happening, as the entity is not empty.
Here's the code of the view controller where I want to display the item's details.
Hope somebody can give me a hand.
Cheers!
import UIKit
class productQuantityViewController: UIViewController {
var myCart: Cart!
#IBOutlet weak var productImage: UIImageView!
#IBOutlet weak var productNameLabel: UILabel!
#IBOutlet weak var productDescriptionLabel: UILabel!
#IBOutlet weak var productAmountLabel: UITextField!
#IBOutlet weak var minusButton: UIButton!
#IBOutlet weak var plusButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
productImage.layer.cornerRadius = 10
minusButton.layer.cornerRadius = minusButton.frame.size.width/2
plusButton.layer.cornerRadius = plusButton.frame.size.width/2
showMeTheGoodiesTwo(entry: myCart)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func showMeTheGoodiesTwo(entry: Cart) {
let name = entry.product
let quantity = entry.inventory
let description = entry.productDescription
let image = entry.productImage as Data?
let xNSNumber = quantity as NSNumber
productNameLabel!.text = name
productDescriptionLabel!.text = description
productAmountLabel!.text = xNSNumber.stringValue
productImage!.image = UIImage(data:image!)
print(productNameLabel.text as Any)
}
}
You need to change
var myCart: Cart!
To
var myCart: Cart?
? is use to make it optional.
And in viewDidLoad use
if (myCart != nil){
showMeTheGoodiesTwo(entry: myCart)
} else {
//do something.
}
instead of
showMeTheGoodiesTwo(entry: myCart)

Geting a fatal "error: unexpectedly found nil while unwrapping an Optional value" when chaging value of label on button press

I keep getting nil value when I press button.
import UIKit
class ViewController: UIViewController {
//MARK: Properties
#IBOutlet weak var txt_vrednost: UITextField!
#IBOutlet weak var btn_dodaj: UIButton!
#IBOutlet weak var lbl_stanje: UILabel!
var novcanik = 0.0
//MARK: Acttion
#IBAction func btn_dodaj_pressed(_ sender: Any) {
let values = Double(txt_vrednost.text!)
novcanik = novcanik + values!
lbl_stanje.text=String(novcanik)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
First of all make sure all your outlets are connected with storyboard. You are using force unwrap everywhere, which is causing crash :
import UIKit
class ViewController: UIViewController {
//MARK: Properties
#IBOutlet weak var txt_vrednost: UITextField!
#IBOutlet weak var btn_dodaj: UIButton!
#IBOutlet weak var lbl_stanje: UILabel!
var novcanik = 0.0
//MARK: Action
#IBAction func btn_dodaj_pressed(_ sender: Any) {
guard let values = txt_vrednost.text as? Double else {
print("not convertible")
return
}
novcanik = novcanik + values
lbl_stanje.text = "\(novcanik)"
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}

Add the value of multiple sliders in swift then average them?

Im doing this wrong I but I'm not sure how to get it I could really use some help. I have 3 sliders (I may need more later) and basically they are 1-10 in value kinda for a rating system and i want them averaged to create an average score.. so this is what I have
#IBOutlet weak var speed: UISlider!
#IBAction func speedChange(sender: AnyObject) {
let speedValue = speed.value
}
#IBOutlet weak var body: UISlider!
#IBAction func bodyChange(sender: AnyObject) {
let bodyValue = body.value
}
#IBOutlet weak var details: UISlider!
#IBAction func detailsChange(sender: AnyObject) {
let detailsValue = details.value
}
#IBOutlet weak var score: UILabel!
func final() {
var thescore = (speed.value + body.value + details.value) / 3
score.text = "\(thescore)"
}
Only problem is it doesn't work. the + errors out, so I need to fix that, but even still i think my methodology is completely off.
It worked for me. Are you sure the outlets in the storyboard are linked to your Controller ?
Also, you may want to call your function final every time a slider changed its value, like this :
#IBOutlet weak var sliderA: UISlider!
#IBAction func sliderAchanged(sender: AnyObject) {
fonction()
}
#IBOutlet weak var sliderB: UISlider!
#IBAction func sliderBchanged(sender: AnyObject) {
fonction()
}
#IBOutlet weak var sliderC: UISlider!
#IBAction func sliderCchanged(sender: AnyObject) {
fonction()
}
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
fonction()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func fonction() {
var thescore = (sliderA.value + sliderB.value + sliderC.value ) / 3
label.text = "\(thescore)"
}​
And I added a call to the function in viewDidLoad method to initilaize the label's text.

Array of UIButtons or method UIButton(named: "\(string)")

Is it possible to make an array of UIButtons?
let buttonArray: [UIButton] = [UIButton(Button1)!, UIButton(Button2)!, UIButton(Button3)!]
To reference later as
buttonArray[0].setImage(UIImage, forState: UIControlState.Normal)
Or somehow set a
var button = UIButton.whoseName = "Specific String"
button.setImage(UIImage, forState: UIControlState.Normal)
VC1:
import UIKit
class VC1: UIViewController {
#IBOutlet weak var Card1: UIButton!
#IBOutlet weak var Card2: UIButton!
#IBOutlet weak var Card3: UIButton!
let Cards: [UIImage] = [UIImage(named: "Default")!, UIImage(named: "2s")!,UIImage(named: "2h")!,UIImage(named: "2c")!,UIImage(named: "2d")!,]
// var CardCaller: Array<UIButton> = [Card1, Card2, Card3]
let CardCallers: [UIButton] = [Card1, Card2, Card3] //ERROR: 'VC1.Type' does not have a member named 'Card1'
var caller = ""
var Index2 = Int()
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.
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let KVC = segue.destinationViewController as VC2
KVC.source = segue.identifier!
}
#IBAction func unwind(unwindSegue: UIStoryboardSegue){
//Card1.setImage(Cards[Index2], forState: UIControlState.Normal)
//let button = UIButton(named: "Card1")!
if caller == "Card1" {Card1.setImage(Cards[Index2], forState: UIControlState.Normal)} else if caller == "Card2" {Card2.setImage(Cards[Index2], forState: UIControlState.Normal)} else if caller == "Card3" {Card3.setImage(Cards[Index2], forState: UIControlState.Normal)}
}
#IBAction func text(sender: AnyObject) {
println(caller)
println(Index2)
}
}
The IBOutlets are wired properly to Storyboard buttons; I created them with control/drag to the view controller.
This shouldn't be a problem, but it may have something to do with when you're accessing the buttons. Try creating the array globally and adding the buttons to it once they've loaded:
class VC1: UIViewController {
#IBOutlet weak var Card1: UIButton!
#IBOutlet weak var Card2: UIButton!
#IBOutlet weak var Card3: UIButton!
var CardCallers: [UIButton] = [UIButton]() // Empty UIButton array
override func viewDidLoad() {
self.CardCallers = [self.Card1, self.Card2, self.Card3] // Buttons have now loaded in the view
}
}
You can.
Two ways to do it:
var buttonsArray: Array<UIButton> = [button1, button2]
Or
#IBOutlet var buttonsArray: Array<UIButton> = []
For the later one, it can be filled from the storyboard as an IBOutletCollection
Please note that views can be assigned to an IBOutlet and an IBOutletCollection at the same time.

Resources