2016-07-22 35 views
0

Ich wollte neulich einen Average-Calculator programmieren. Mein Plan war es, eine UITextField zu erstellen, in der Sie Zahlen durch Kommata getrennt eingeben können ... Durch Drücken der Schaltfläche "Berechnen" sollte die App den Durchschnitt der Zahlen oben berechnen und sie ausgeben, indem Sie einen labeltext auf den Durchschnitt setzen. Also schrieb ich meine durchschnittliche Funktion und erhielt diese Fehlermeldung:Textfeld als Eingabe in der Durchschnittsfunktion

Wert kann nicht vom Typ umwandeln ‚UITextField‘ zu erwarten Elementtyp ‚Double‘.

Das ist mein Code:

@IBOutlet var Input: UITextField! 
@IBOutlet var Output: UILabel! 
@IBAction func Calculate(sender: AnyObject) { 

    var grades:[Double] = [Input] 
    func average(nums: [Double]) -> Double { 

     var total = 0.0 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     let average = total/gradesTotal 
     return average 
    } 

    let Average = average(grades) 

    Output.text = "Average: \(Average)" 
} 

Können Sie mir mit meiner Idee helfen? Gibt es einen besseren Weg, um eine Eingabe zu erhalten?

+0

verwenden Sie 'Double (Input.text)'. Sie vergeben jetzt ein Textfeld-Objekt an das doppelte –

Antwort

2

Bitte verwenden Sie niedrigere Camel Case für Variablen ...

In dieser Zeile:

var grades:[Double] = [Input] 

Input ist eine Instanz UITextField, so dass Sie versuchen, ein Einzelelement Array<UITextField> zu Array<Double> zuzuweisen. Du siehst, du kannst so etwas nicht tun.

Wenn Sie einen Text annehmen möchten, die durch Kommata getrenntZahlen enthält, müssen Sie explizit die text-[Double] konvertieren.

Um zu vereinfachen, ignorieren wir einfach die nil oder nicht-numerische Werte. Dann müssen Sie Ihren Code so ändern:

@IBOutlet var input: UITextField! 
@IBOutlet var output: UILabel! 
@IBAction func calculate(sender: AnyObject) { 

    var grades: [Double] = (input.text ?? "").componentsSeparatedByString(",").flatMap{Double($0)} 
    func average(nums: [Double]) -> Double { 

     var total = 0.0 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     let average = total/gradesTotal 
     return average 
    } 

    let averageValue = average(grades) 

    output.text = "Average: \(averageValue)" 
} 

Die Grundidee dieser Linie:

var grades: [Double] = (input.text ?? "").componentsSeparatedByString(",").flatMap{Double($0)} 

ist gut beschrieben in Lu_ Antwort. Meins ist nur eine etwas sicherere Version.


(Addition) Eine Erklärung über die Sicherheit:

UITextField Eigentum text ist vom Typ String?, so denken Sie, sollte es gleich Null sein kann. Geben Sie einen Standardwert für null mit ?? Operator.

Und die Verwendung von Double($0)! kann zum Absturz Ihrer App führen, da Double($0) NULL für nicht-numerische Zeichenfolgen zurückgibt.

Schreiben diese erinnerte mich noch einen Crashfall.

Wenn gradesTotal == 0, wird der obige Code mit Division durch Null abstürzen.

(Der default Wert funktioniert nicht gut für "Sicherheit" im Code oben ...)

Also, ein weiterer Schritt voraus zu Sicherheit:

@IBAction func calculate(sender: AnyObject) { 

    var grades: [Double] = (input.text ?? "").componentsSeparatedByString(",").flatMap{ 
     Double($0.stringByTrimmingCharactersInSet(.whitespaceCharacterSet())) 
    } 
    func average(nums: [Double]) -> Double? { 

     var total = 0.0 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     if gradesTotal > 0 { 
     let average = total/gradesTotal 
      return average 
     } else { 
      return nil 
     } 
    } 

    if let averageValue = average(grades) { 
     output.text = "Average: \(averageValue)" 
    } else { 
     output.text = "Average not available" 
    } 
} 
+0

Vielen Dank! Es hat funktioniert! :) – Cave007

+0

Danke für die Berichterstattung. Bitte denken Sie daran, dass diese Antwort durch die Zusammenarbeit der Stack Overflow Community verbessert wurde. Und hoffe, dass deine Erfahrung anderen Community-Mitgliedern hilft. Viel Glück für dich und deine App. – OOPer

+0

Ich weiß nicht warum, aber wenn ich die App jetzt starte bricht sie um @IBOutlet var input: UITextField! Es funktionierte perfekt, aber weiß, es bricht jedes Mal ... Ich glaube nicht, dass ich etwas geändert habe ... Ich habe sogar den Code gelöscht, so dass es nur die Ansicht ohne Funktionalität, aber es brach auch ... – Cave007

0

Was Sie tun müssen, ist Double(Input.text) statt [Input] zu verwenden. Sie haben gerade versucht, ein UITextField in ein Double zu konvertieren, das den Fehler verursacht.

4

Sie müssen Zahlen trennen das Array zu erhalten, wenn Sie das tun: enter image description here

Sie "Doppel" Array Ihre durchschnittliche Funktion

Code zu Copypaste passieren kann :)

var str = "1,2,3,4,5,6" 

let stringsWithNumbers = str.componentsSeparatedByString(",") 

let doubles = stringsWithNumbers.map { Double($0)! } 
+1

Nizza! Dies betrifft beide Probleme in der Frage. – sbarow

+1

versehentlich entfernt Kommentar, sorry, wollte nur zu zitieren. Code hinzugefügt danke für die Erinnerung daran. –

+1

Gern geschehen. Ich versuche so schnell wie möglich veraltete Kommentare freizugeben. – vacawama

0
let textInput = txtInputView.text; 
let components = textInput.componentsSeparatedByString(","); 
let sum = 0.0; 
for txt in components 
{ 
    sum = sum + Double(txt); 
} 

let avg = sum/components.count; 
print(avg) 
0

Hier die ist vollständiger Code, wenn jemand interessiert :)

@IBOutlet var input: UITextField! 
@IBOutlet var output: UILabel! 
@IBAction func calculate(sender: AnyObject) { 

    var grades: [Double] = (input.text ?? "").componentsSeparatedByString(",").flatMap{ 
     Double($0.stringByTrimmingCharactersInSet(.whitespaceCharacterSet())) 
    } 
    func average(nums: [Double]) -> Double? { 

     var total = 0.0 
     for grade in nums{ 

      total += Double(grade) 
     } 

     let gradesTotal = Double(nums.count) 
     if gradesTotal > 0 { 
      let average = total/gradesTotal 
      return average 
     } else { 
      return nil 
     } 
    } 

    if let averageValue = average(grades) { 
     output.text = "Average: \(averageValue)" 
    } else { 
     output.text = "Average not available" 
    } 

} 

@IBAction func userTappedCalculate(sender: AnyObject) { view.endEditing(true) 
} 

ich die Linie @IBAction func userTappedCalculate(sender: AnyObject) { view.endEditing(true) } hinzugefügt, um den Eingang Tex zu schließen tFeld, wenn Sie auf Berechnen tippen ...