2014-12-22 17 views
36

Sono nuovo di Swift, come posso convertire una stringa in CGFloat?Converti stringa in CGFloat in Swift

ho provato:

var fl: CGFloat = str as CGFloat 
var fl: CGFloat = (CGFloat)str 
var fl: CGFloat = CGFloat(str) 

non tutto ha funzionato

+3

Avete bisogno di gestire gli utenti internazionali? (Ad esempio, in Germania, la virgola viene utilizzata come separatore decimale.) In tal caso, considerare l'utilizzo di 'NSNumberFormatter', che utilizzerà le impostazioni di internazionalizzazione del dispositivo per gestire i numeri nel formato preferito dell'utente. – Rob

+2

grazie ma l'internazionalizzazione non è un problema qui – foreyez

risposta

85

Se volete un modo sicuro per fare questo, qui è una possibilità:

Se si modifica str in "bob", non verrà convertito in float, mentre la maggior parte delle altre risposte sarà diventa trasformato in 0.0.

per SWIFT 3.0, mi piacerebbe fare qualcosa di simile:

let str = "32.4" 
guard let n = NSNumberFormatter().number(from: str) else { return } 
// Use `n` here 

a Swift 4, NSNumberFormatter è stato rinominato NumberFormatter:

let str = "32.4" 
guard let n = NumberFormatter().number(from: str) else { return } 
+1

Nessuna delle altre risposte gestisce l'input dell'utente internazionale. Se questa stringa viene immessa da un utente, è necessario utilizzare una risposta specifica di "locale" come questa (o 'NSScanner'). – Rob

+1

Non avevo nemmeno pensato alla localizzazione. (Ammettiamolo, è qualcosa che anche i migliori programmatori spesso non considerano). Ma hai ragione. –

+1

Sembra che non ci sia 'NSNumberFormatter' in Swift 4.0. –

1

Buona domanda. Non c'è infatti API Swift pura per convertire una stringa che rappresenta un CGFloat in un CGFloat. L'unico numero rappresentato da una stringa che puro Swift ti consente di convertire in un numero è un numero intero. Dovrai utilizzare qualche altro approccio da qualche altra libreria - ad esempio, iniziare con NSString della Fondazione o C (Darwin) strtod.

+0

facepalm. Apprezzo la risposta, ma qualsiasi trucco per farlo? (cioè codice). venendo da javascript è come tornare al XVIII secolo qui. – foreyez

+0

'NSNumberFormatter' è anche una possibilità, anche se dubito che sia altrettanto efficiente. Unsafely: 'CGFloat (formatter.numberFromString (" 23.4 ")!)'. –

+0

sì, la risposta di vacawama. nel caso in cui non steste prestando attenzione, Stackoverflow è il mio uomo. – foreyez

10

Questo funziona:

let str = "3.141592654" 
let fl = CGFloat((str as NSString).floatValue) 
+2

Lo svantaggio di questo è che '(str as NSString) .floatValue' dà 0 per le stringhe che non capisce, come" bob ". Questa potrebbe essere una caratteristica o un bug in base alle tue esigenze. Non userei questo metodo se accettassi un input non attendibile. Invece, userei 'NSNumberFormatter' o simili. –

+1

grazie, è affidabile anche se – foreyez

1

questo è una specie di un lavoro in giro, ma si può lanciare come un NSString, quindi ottenere il valore float, quindi inizializzare una CGFloat da quel valore. Esempio:

let str = "1.02345332" 
let foo = CGFloat((str as NSString).floatValue) 
13

Si dovrebbe lanciare string-double e poi gettato double-CGFloat, Let provate questo:

let fl: CGFloat = CGFloat((str as NSString).doubleValue) 
+1

Passare da float a CGFloat può causare una perdita di precisione (provatelo con 0,57). Passare da doppio a CGFloat mantiene il valore corretto. – Maxwell

+0

@Maxwell per ora. In futuro potrebbero essere disponibili altri tipi di virgola mobile. Inoltre, esiste una buona ragione per cui esiste CGFloat' al posto di 'float' e' double': viene eseguito più velocemente su processori a 32 bit. Affidarsi a IEEE 64-bit float per mantenere un valore corretto è miope nel migliore dei casi. –

5

Mentre le altre risposte sono corrette, ma il il risultato che vedrai avrà dei decimali finali.

Ad esempio:

let str = "3.141592654" 
let foo = CGFloat((str as NSString).floatValue) 

Risultato:

3.14159274101257 

per ottenere un valore corretto indietro dalla stringa, provare quanto segue:

let str : String = "3.141592654" 
let secStr : NSString = str as NSString 
let flt : CGFloat = CGFloat(secStr.doubleValue) 

Risultato:

3.141592654 
+1

abbastanza giusto, preferisco il tuo – foreyez

+0

in realtà, aspetterò i upvotes per decidere chi ottiene la risposta. grazie comunque. – foreyez

13

A partire da Swift 2.0, il tipo Double ha un inizializzatore disponibile che accetta un String.Quindi il modo più sicuro per andare String-CGFloat è:

let string = "1.23456" 
var cgFloat: CGFloat? 

if let doubleValue = Double(string) { 
    cgFloat = CGFloat(doubleValue) 
} 

// cgFloat will be nil if string cannot be converted 

Se dovete fare questo, spesso, è possibile aggiungere un metodo di estensione per String:

extension String { 

    func CGFloatValue() -> CGFloat? { 
    guard let doubleValue = Double(self) else { 
     return nil 
    } 

    return CGFloat(doubleValue) 
    } 
} 

Si noti che si dovrebbe restituire un CGFloat? poiché l'operazione può fallire.

8

a Swift 3,0

if let n = NumberFormatter().number(from: string) { 
    let f = CGFloat(n) 
} 

o questo se si è certi che stringa soddisfa tutti i requisiti

let n = CGFloat(NumberFormatter().number(from: string)!) 
2

a Swift 3,1

if let n = NumberFormatter().number(from: string) { 
    let fl = CGFloat(n) 
} 

o:

let fl = CGFloat((str as NSString).floatValue)) 
0

È possibile effettuare un'estensione che aggiunge un init per CGFloat

extension CGFloat { 

    init?(string: String) { 

     guard let number = NumberFormatter().number(from: string) else { 
      return nil 
     } 

     self.init(number.floatValue) 
    } 

} 

utilizzarlo come modo let x = CGFloat(xString)