Divide text fields

I am trying to divide two text fields and update another field. Basically I am trying to make a percentage. I am confused as to how to label things and where to put them in the file. I have tried multiple searches on other sites with no resolution. If anyone can help I would very much appreciate some guidance. If you need more information or code please let me know. Thanks in advance.

If I understand your intent correctly:


- create 2 IBOutlets textFields, numeratorField and denominatorField

- set the delegate for the textFields to File owner

- create an IBOutlet percentage, with a label


- connect "Did End On Exit" action event in Interface Builder for each textField to a method that will compute the percentage

- if you want to compute the percentage on the fly, you should connect "Editing changed"


THe method will read the value of the 2 text fields, and ifdenominator is not zero, compute the percentage ; then set the text of the percentage label

Yes this sounds like what I am looking to do. I will work on this later and reply with any questions and update if it worked. Thank you so much for the help.

I played with it a bit and I'm still having a bit of difficulty...I am copying and pasting some code which I think should work...it divides the fields and I can get the percentage but if I leave the numerator or denominator field blank it will crash the app and give me found a nil while unwrapping an optional....i've tried to figure this out and am closer but any further guidance and possible explanation would be beneificial...thanks in advance



@IBOutlet weak var numeratorField: UITextField!

@IBOutlet weak var denominatorField: UITextField!

@IBOutlet weak var percentageLabel: UILabel!

@IBAction func numeratorEditing(sender: AnyObject) {

let percent: Double = Double(Double(denominatorField.text!)! / Double(numeratorField.text!)!) * 100

percentageLabel.text = ("\(percent)%")

}

@IBAction func denominatorEditing(sender: AnyObject) {

let percent: Double = Double(Double(denominatorField.text!)! / Double(numeratorField.text!)!) * 100

percentageLabel.text = ("\(percent)%")

}


Xcode makes me add the ! symbol in the function areas as I thought that was causing the issue and it very might be but I am unable to find the fix

You should have some more tests, otherwise, some fields may effectively be undefined.


The same function may be used for both fields : connect the "Did End On Exit" action of each field to this function ; so I call the func fieldEditing


You had also mixed numerator and denominator


I would write this (you may have to fine tune) :


func fieldEditing(sender: AnyObject) {         //  a field was edited
    var denominatorValue = Double(0)          // let's first read the denominator
    if let denominator = denominatorField.text  {        // You know you have some text
        if let value = Double(denominator) {                // you have a value in the text ; you could combien the 2 lines, but it will be easier to understand with 2 seperate tests
            denominatorValue = value
            // You must also test that the value is not zero (to avoid a divide by zero), but the test cannot be done directly on Double ; so you can test that 1000 * denominator is not 0, as an Int
            if Int(1000 * denominator) == 0 { return }
        } else {
            return
        }
    } else {
        return
    }

    var numeratorValue = Double(0)          // Do quite the same for numerator
    if let numerator = numeratorField.text  {
        if let value = Double(numerator) {
            numeratorValue = value
        } else {
            return
        }
    } else {
        return
    }
       // Now, the 2 values do exist and denominator is not zero
    let percent = Double(numeratorValue / denominatorValue * 100)
    percentageLabel.text = ("\(percent)%")
}

thank you so much for the very detailed response. I will be working on this tomorrow after work. I'll let you know if I have further questions. Thank you so much once again.

I'm still not getting the functionality I need. I think it has to do where I am placing the function. I am sorry for all the questions but I am brand new to swift and learning how to creat this app. The app will build successfully and it won't crash but it's not saving my inputs and it's not calculating the percentage and the field isn't showing up. Here is the viewcontroller code. Let me know where I should put the code if not where it is. I am trying to take the current page number and divide it by the total pages to give a percentae or basically how far you are in the book.

/

/

/

/

/

/

/

import UIKit

class ViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

/


@IBOutlet weak var titleTextField: UITextField!

@IBOutlet weak var authorTextField: UITextField!

@IBOutlet weak var photoImageView: UIImageView!

@IBOutlet weak var ratingControl: RatingControl!

@IBOutlet weak var saveButton: UIBarButtonItem!

@IBOutlet weak var currentPage: UITextField!

@IBOutlet weak var numberPages: UITextField!

@IBOutlet weak var numberDays: UITextField!

@IBOutlet weak var percentageLabel: UILabel!

@IBAction func percentagePages (sender: AnyObject) {

func fieldEditing(sender: AnyObject) { /

var denominatorValue = Double(0) /

if let denominator = numberPages.text { /

if let value = Double(denominator) { /

denominatorValue = value

/

if (1000 * Int(denominator)!) == 0 { return }

} else {

return

}

} else {

return

}

var numeratorValue = Double(0) /

if let numerator = currentPage.text {

if let value = Double(numerator) {

numeratorValue = value

} else {

return

}

} else {

return

}

/

let percent = Double(Double(numeratorValue) / Double(denominatorValue) * 100)

percentageLabel.text = ("\(percent)%")

}

}

@IBAction func percentageCurrent(sender: AnyObject) {

func fieldEditing(sender: AnyObject) { /

var denominatorValue = Double(0) /

if let denominator = numberPages.text { /

if let value = Double(denominator) { /

denominatorValue = value

/

if Int(1000 * Int(denominator)!) == 0 { return }

} else {

return

}

} else {

return

}

var numeratorValue = Double(0) /

if let numerator = currentPage.text {

if let value = Double(numerator) {

numeratorValue = value

} else {

return

}

} else {

return

}

/

let percent = Double(numeratorValue / denominatorValue * 100)

percentageLabel.text = ("\(percent)%")

}

}



/

This value is either passed by `BookTableViewController` in `prepareForSegue(_:sender:)`

or constructed as part of adding a new book.

*/

var book: Book?


override func viewDidLoad() {

super.viewDidLoad()

/

titleTextField.delegate = self

/

if let book = book {

navigationItem.title = book.title

titleTextField.text = book.title

photoImageView.image = book.photo

ratingControl.rating = book.rating

authorTextField.text = book.author

currentPage.text = book.current

numberPages.text = book.pages

numberDays.text = book.days

percentageLabel.text = book.percentage

}

/

checkValidBookName()

}


/


func textFieldShouldReturn(textField: UITextField) -> Bool {

/

textField.resignFirstResponder()

return true

}


func textFieldDidEndEditing(textField: UITextField) {

checkValidBookName()

navigationItem.title = textField.text

}


func textFieldDidBeginEditing(textField: UITextField) {

/

saveButton.enabled = false

}


func checkValidBookName() {

/

let text = titleTextField.text ?? ""

saveButton.enabled = !text.isEmpty

}


/

func imagePickerControllerDidCancel(picker: UIImagePickerController) {

/

dismissViewControllerAnimated(true, completion: nil)

}


func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {

/

let selectedImage = info[UIImagePickerControllerOriginalImage] as! UIImage

/

photoImageView.image = selectedImage

/

dismissViewControllerAnimated(true, completion: nil)

}


/

@IBAction func cancel(sender: UIBarButtonItem) {

/

let isPresentingInAddBookMode = presentingViewController is UINavigationController

if isPresentingInAddBookMode {

dismissViewControllerAnimated(true, completion: nil)

} else {

navigationController!.popViewControllerAnimated(true)

}

}


/

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if saveButton === sender {

let title = titleTextField.text ?? ""

let photo = photoImageView.image

let rating = ratingControl.rating

let author = authorTextField.text

let current = currentPage.text

let pages = numberPages.text

let days = numberDays.text

let percentage = percentageLabel.text

/

book = Book(title: title, author: author!, current: current!, pages: pages!, days: days!, photo: photo, rating: rating, percentage: percentage!)

}

}


/


func selectImageFromPhotoLibrary(sender: UITapGestureRecognizer) {

/

titleTextField.resignFirstResponder()

/

let imagePickerController = UIImagePickerController ()

/

imagePickerController.sourceType = .PhotoLibrary

/

imagePickerController.delegate = self

presentViewController(imagePickerController, animated: true, completion: nil)

}

}

I see a first error :


@IBAction func percentagePages (sender: AnyObject) {

func fieldEditing(sender: AnyObject) {


fieldEditing is never called.


You should not define a func inside percentagePages. What you should write is :


@IBAction func percentagePages (sender: AnyObject) {
            var denominatorValue = Double(0)
            if let denominator = numberPages.text  {
                if let value = Double(denominator) {
                    denominatorValue = value
                    /
                    if (1000 * Int(denominator)!) == 0 { return }
                } else {
                    return
                }
            } else {
                return
            }
   
            var numeratorValue = Double(0)
            if let numerator = currentPage.text  {
                if let value = Double(numerator) {
                    numeratorValue = value
                } else {
                    return
                }
            } else {
                return
            }

            let percent = Double(Double(numeratorValue) / Double(denominatorValue) * 100)
            percentageLabel.text = ("\(percent)%")
    }


And do the same with percentageCurrent


    @IBAction func percentageCurrent(sender: AnyObject) {
            var denominatorValue = Double(0)          /
            if let denominator = numberPages.text  {        /
                if let value = Double(denominator) {                /
                    denominatorValue = value
                    /
                    if Int(1000 * Int(denominator)!) == 0 { return }
                } else {
                    return
                }
            } else {
                return
            }
    
            var numeratorValue = Double(0)          /
            if let numerator = currentPage.text  {
                if let value = Double(numerator) {
                    numeratorValue = value
                } else {
                    return
                }
            } else {
                return
            }
            /
            let percent = Double(numeratorValue / denominatorValue * 100)
            percentageLabel.text = ("\(percent)%")
    }



Don't forget to connect the connect the "Did End On Exit" "message sent button" of each field to percentagePages and "Edited changed" action of each field to percentageCurrent.


You may notice that the 2 functions are exactly the same. You could defione only one, and connect all to the same.


Divide text fields
 
 
Q