Swift aplica .uppercaseString solo a la primera letra de una cadena

232

Estoy tratando de hacer un sistema de autocorrección, y cuando un usuario escribe una palabra con una letra mayúscula, la autocorrección no funciona. Para solucionar esto, hice una copia de la cadena escrita, apliqué .lowercaseString y luego las comparé. Si la cadena está mal escrita, debería corregir la palabra. Sin embargo, entonces la palabra que reemplaza la palabra escrita es minúscula. Entonces necesito aplicar .uppercaseString solo a la primera letra. Originalmente pensé que podría usar

nameOfString[0]

pero esto aparentemente no funciona. ¿Cómo puedo poner la primera letra de la cadena en mayúscula y luego poder imprimir la cadena completa con la primera letra en mayúscula?

¡Gracias por cualquier ayuda!

Algún chico
fuente

Respuestas:

512

Incluyendo versiones mutantes y no mutantes que son consistentes con las pautas API.

Swift 3:

extension String {
    func capitalizingFirstLetter() -> String {
        let first = String(characters.prefix(1)).capitalized
        let other = String(characters.dropFirst())
        return first + other
    }

    mutating func capitalizeFirstLetter() {
        self = self.capitalizingFirstLetter()
    }
}

Swift 4:

extension String {
    func capitalizingFirstLetter() -> String {
      return prefix(1).uppercased() + self.lowercased().dropFirst()
    }

    mutating func capitalizeFirstLetter() {
      self = self.capitalizingFirstLetter()
    }
}
Kirsteins
fuente
3
Solo una nota que .capitalizedStringya no funciona en Xcode 7 Beta 4. Las cadenas han cambiado un poco en Swift 2.0.
kakubei
2
@ Kirsteins: tienes razón, mi mal. Había olvidado importar Foundation sonrisa tímida
kakubei
3
@LoryLory Uso .uppercaseStringpara eso
Kirsteins
2
Este es el compañero de respuesta realmente efectivo ... Trabajando con Xcode 7.1.1 / Swift 2.1 .... Gracias :)
onCompletion
20
Es solo .capitalizedahora. Tenga en cuenta tambiéncapitalizedStringWith(_ locale:)
Raphael
152

Swift 5.1 o posterior

extension StringProtocol {
    var firstUppercased: String { prefix(1).uppercased() + dropFirst() }
    var firstCapitalized: String { prefix(1).capitalized + dropFirst() }
}

Swift 5

extension StringProtocol {
    var firstUppercased: String { return prefix(1).uppercased() + dropFirst() }
    var firstCapitalized: String { return prefix(1).capitalized + dropFirst() }
}

"Swift".first  // "S"
"Swift".last   // "t"
"hello world!!!".firstUppercased  // "Hello world!!!"

"DŽ".firstCapitalized   // "Dž"
"Dž".firstCapitalized   // "Dž"
"dž".firstCapitalized   // "Dž"
Leo Dabus
fuente
3
Buen trabajo. Edité el mío para pasar primero en minúscula y cambié el nombre a Proper.
ericgu
Me gusta la solución swift 2.1.1, pero cuando ejecuto mi aplicación y compruebo si hay fugas, muestra que está goteando.
Henny Lee
1
Acabo de crear un nuevo proyecto y parece que causa una pérdida de memoria cuando se usa junto con un UITextFieldobservador UITextFieldTextDidChangeNotification.
Henny Lee
@ Henry esto no tiene nada que ver con el código en sí. Si experimenta algún problema de rendimiento / memoria, debe informarlo a Apple.
Leo Dabus el
1
@LeoDabus, creo que depende de cuál hace que la intención del código sea más evidente. El literal de cadena vacío es quizás el mejor.
Nicolas Miari
84

Swift 3.0

para "Hello World"

nameOfString.capitalized

o para "HOLA MUNDO"

nameOfString.uppercased
Maselko
fuente
3
Charlesism ya ha respondido con la versión Swift 3 hace dos meses ...
Eric Aya
11
Esto capitalizará el primer carácter de cada palabra de la Cadena y no solo la primera palabra.
Bocaxica
Devuelve: una copia en mayúscula de la cadena. func pública en mayúsculas () -> String Swift 3.0 o para "HOLA MUNDO" nameOfString.uppercased EN LUGAR DE ARRIBA nameOfString.uppercased ()
Azharhussain Shaikh
40

Swift 4.0

string.capitalized(with: nil)

o

string.capitalized

Sin embargo, esto pone en mayúscula la primera letra de cada palabra

Documentación de Apple:

Una cadena en mayúscula es una cadena con el primer carácter de cada palabra cambiado a su valor en mayúscula correspondiente, y todos los caracteres restantes configurados en sus valores en minúscula correspondientes. Una "palabra" es cualquier secuencia de caracteres delimitada por espacios, tabulaciones o terminadores de línea. No se considera alguna puntuación común delimitadora de palabras, por lo que esta propiedad generalmente no produce los resultados deseados para cadenas de varias palabras. Consulte el método getLineStart (_: end: contentsEnd: for :) para obtener información adicional.

sam k
fuente
1
No tengo idea de por qué las personas no son receptivas a esta respuesta. Si las personas quieren solo la primera palabra en mayúscula, pueden tomar la primera y capitalizarla más fácilmente con la propiedad en mayúscula.
ScottyBlades
1
Es importante destacar que "Capitalizado" es correcto para todos los caracteres Unicode, mientras que el uso de "mayúsculas" para el primer carácter no lo es.
gnasher729
23
extension String {
    func firstCharacterUpperCase() -> String? {
        let lowercaseString = self.lowercaseString

        return lowercaseString.stringByReplacingCharactersInRange(lowercaseString.startIndex...lowercaseString.startIndex, withString: String(lowercaseString[lowercaseString.startIndex]).uppercaseString)
    }
}

let x = "heLLo"
let m = x.firstCharacterUpperCase()

Para Swift 5:

extension String {
    func firstCharacterUpperCase() -> String? {
        guard !isEmpty else { return nil }
        let lowerCasedString = self.lowercased()
        return lowerCasedString.replacingCharacters(in: lowerCasedString.startIndex...lowerCasedString.startIndex, with: String(lowerCasedString[lowerCasedString.startIndex]).uppercased())
    }
}
usuario2260304
fuente
Esta es la mejor respuesta de la OMI: es simple para todos los casos futuros.
Robert
No es necesario verificar si la cadena isEmptye inicializar una cadena para reemplazar tampoco. Simplemente puede desenvolver el primer carácter y en caso de que falle simplemente devuelva nil. Esto se puede simplificar comovar firstCharacterUpperCase: String? { guard let first = first else { return nil } return lowercased().replacingCharacters(in: startIndex...startIndex, with: first.uppercased()) }
Leo Dabus
17

Para el primer carácter en el uso de palabras .capitalizeden Swift y para uso de palabras completas.uppercased()

DURGESH
fuente
10

Swift 2.0 (línea única):

String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst())
Phil
fuente
1
Votado Sin embargo, esto supone que la cadena original es todo en minúsculas. He añadido .localizedLowercaseStringal final para que funcione con cadenas como: aNYsTring. String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst()).localizedLowercaseString
oyalhi
4

Swift 3 (xcode 8.3.3)

Todos los primeros caracteres de cadena en mayúscula

let str = "your string"
let capStr = str.capitalized

//Your String

Todos los caracteres en mayúscula

let str = "your string"
let upStr = str.uppercased()

//YOUR STRING

Solo primer carácter en mayúscula de la cadena

 var str = "your string"
 let capStr = String(str.characters.prefix(1)).uppercased() + String(str.characters.dropFirst())

//Your string
Oscar Castellon
fuente
Esto no capitalizará solo el primer carácter de una cadena
Rool Paap el
3

Estoy obteniendo el primer personaje duplicado con la solución de Kirsteins. Esto capitalizará el primer personaje, sin ver doble:

var s: String = "hello world"
s = prefix(s, 1).capitalizedString + suffix(s, countElements(s) - 1)

No sé si es más o menos eficiente, solo sé que me da el resultado deseado.

Marc Fearby
fuente
Podrías probar si poner en mayúscula el primer carácter cambia ese carácter, guardándolo en su propia constante y luego probando la igualdad con la nueva cadena 'mayúscula', y si son iguales, entonces ya tienes lo que quieres.
David H
Su publicación inspiró esta respuesta: ¡gracias !: func capitaizeFirstChar (var s: String) -> String {if s.isEmpty == false {let range = s.startIndex ... s.startIndex let original = s.substringWithRange (range) let capitalized = original.capitalizedString if original == capitalized {return s} s.replaceRange (range, with: capitalized)} return s}
David H
1
En las versiones más recientes de Swift, countElementses justo count.
George Poulos
3

Desde Swift 3 puedes usar fácilmente textField.autocapitalizationType = UITextAutocapitalizationType.sentences

Yura
fuente
3

Aquí hay una versión para Swift 5 que usa la API de propiedades escalares Unicode para rescatar si la primera letra ya está en mayúscula o no tiene una noción de mayúsculas y minúsculas:

extension String {
  func firstLetterUppercased() -> String {
    guard let first = first, first.isLowercase else { return self }
    return String(first).uppercased() + dropFirst()
  }
}
Adam Sharp
fuente
No es necesario inicializar una cadena con el primer carácter. return first.uppercased() + dropFirst()o un trazador de líneas(first?.uppercased() ?? "") + dropFirst()
Leo Dabus
2

Poner en mayúscula el primer carácter de la cadena.

extension String {
    var capitalizeFirst: String {
        if self.characters.count == 0 {
            return self

        return String(self[self.startIndex]).capitalized + String(self.characters.dropFirst())
    }
}
usuario3699466
fuente
2

En Swift 3.0 (esto es un poco más rápido y seguro que la respuesta aceptada):

extension String {
    func firstCharacterUpperCase() -> String {
        if let firstCharacter = characters.first {
            return replacingCharacters(in: startIndex..<index(after: startIndex), with: String(firstCharacter).uppercased())
        }
        return ""
    }
}

nameOfString.capitalized no funcionará , capitalizará todas las palabras en la oración

pierre23
fuente
1

Créditos a Leonardo Savio Dabus:

Me imagino que la mayoría de los casos de uso es obtener una carcasa adecuada:

import Foundation

extension String {

    var toProper:String {
        var result = lowercaseString
        result.replaceRange(startIndex...startIndex, with: String(self[startIndex]).capitalizedString)
        return result
    }
}
ericgu
fuente
1

Mi solución:

func firstCharacterUppercaseString(string: String) -> String {
    var str = string as NSString
    let firstUppercaseCharacter = str.substringToIndex(1).uppercaseString
    let firstUppercaseCharacterString = str.stringByReplacingCharactersInRange(NSMakeRange(0, 1), withString: firstUppercaseCharacter)
    return firstUppercaseCharacterString
}
Nazariy Vlizlo
fuente
Esto no es puro rápido.
Abhishek Bedi
1

Al incorporar las respuestas anteriores, escribí una pequeña extensión que escribe en mayúscula la primera letra de cada palabra (porque eso es lo que estaba buscando y pensé que alguien más podría usarla).

Humildemente presento:

extension String {
    var wordCaps:String {
        let listOfWords:[String] = self.componentsSeparatedByString(" ")
        var returnString: String = ""
        for word in listOfWords {
            if word != "" {
                var capWord = word.lowercaseString as String
                capWord.replaceRange(startIndex...startIndex, with: String(capWord[capWord.startIndex]).uppercaseString)
                returnString = returnString + capWord + " "
            }
        }
        if returnString.hasSuffix(" ") {
            returnString.removeAtIndex(returnString.endIndex.predecessor())
        }
        return returnString
    }
}
Mate
fuente
1
Swift String tiene un método llamado capitalizedString. Si necesita aplicarlo a una serie de cadenas, consulte esta respuesta stackoverflow.com/a/28690655/2303865
Leo Dabus
1

Swift 4

func firstCharacterUpperCase() -> String {
        if self.count == 0 { return self }
        return prefix(1).uppercased() + dropFirst().lowercased()
    }
Gayratjon
fuente
0

Esta es la forma en que lo hice en pequeños pasos, es similar a @Kirsteins.

func capitalizedPhrase(phrase:String) -> String {
    let firstCharIndex = advance(phrase.startIndex, 1)
    let firstChar = phrase.substringToIndex(firstCharIndex).uppercaseString
    let firstCharRange = phrase.startIndex..<firstCharIndex
    return phrase.stringByReplacingCharactersInRange(firstCharRange, withString: firstChar)
}
guptron
fuente
0
func helperCapitalizeFirstLetter(stringToBeCapd:String)->String{
    let capString = stringToBeCapd.substringFromIndex(stringToBeCapd.startIndex).capitalizedString
    return capString
}

También funciona, simplemente pasa tu cadena y recupera una en mayúscula.

Dan Leonard
fuente
0

Actualización de Swift 3

El replaceRangefunc es ahorareplaceSubrange

nameOfString.replaceSubrange(nameOfString.startIndex...nameOfString.startIndex, with: String(nameOfString[nameOfString.startIndex]).capitalized)
Brendt Bly
fuente
el método capitalizedString ha cambiado de nombre a capitalized
Rool Paap
0

Soy parcial a esta versión, que es una versión limpia de otra respuesta:

extension String {
  var capitalizedFirst: String {
    let characters = self.characters
    if let first = characters.first {
      return String(first).uppercased() + 
             String(characters.dropFirst())
    }
    return self
  }
}

Se esfuerza por ser más eficiente al evaluar solo los caracteres propios una vez, y luego usa formas consistentes para crear las subcadenas.

Patrick Beard
fuente
0

Swift 4 (Xcode 9.1)

extension String {
    var capEachWord: String {
        return self.split(separator: " ").map { word in
            return String([word.startIndex]).uppercased() + word.lowercased().dropFirst()
        }.joined(separator: " ")
    }
}
Daniel R
fuente
String ya tiene una propiedad llamada capitalizedexactamente para este propósito
Leo Dabus
0

Si desea poner en mayúscula cada palabra de cadena, puede usar esta extensión

Swift 4 Xcode 9.2

extension String {
    var wordUppercased: String {
        var aryOfWord = self.split(separator: " ")
        aryOfWord =  aryOfWord.map({String($0.first!).uppercased() + $0.dropFirst()})
        return aryOfWord.joined(separator: " ")
    }
}

Usado

print("simple text example".wordUppercased) //output:: "Simple Text Example"
Shilpriya
fuente
2
simplemente use.capitalized
kakubei
0

Si su cadena es todo mayúsculas, el siguiente método funcionará

labelTitle.text = remarks?.lowercased().firstUppercased

Esta extensión te ayudará

extension StringProtocol {
    var firstUppercased: String {
        guard let first = first else { return "" }
        return String(first).uppercased() + dropFirst()
    }
}
Ashu
fuente
1
simplemente use.capitalized
kakubei
@kakubei ¿Por qué haces un voto negativo? Este método es para el caso Sentance. Capitalizado hará cada primer carácter de la palabra a capital. Cadena de ejemplo: - (ESTO ES UN NIÑO) .capitalizeddevolverá (Esto es un niño) y este método devolverá (Esto es un niño) Ambos son diferentes. (Por favor, + ve voto negativo o eliminar)
Ashu
Tienes razón @ashu, mis disculpas. Sin embargo, no puedo votar hasta que edite la respuesta, así que tal vez solo haga una pequeña edición de espacios en blanco y la votaré. Lo siento de nuevo.
kakubei
No es necesario inicializar una cadena con el primer carácter. return first.uppercased() + dropFirst()o un regreso de línea(first?.uppercased() ?? "") + dropFirst()
Leo Dabus
0

Agregue esta línea en el método viewDidLoad ().

 txtFieldName.autocapitalizationType = UITextAutocapitalizationType.words
Pranit
fuente
-1
extension String {
    var lowercased:String {
        var result = Array<Character>(self.characters);
        if let first = result.first { result[0] = Character(String(first).uppercaseString) }
        return String(result)
    }
}
john07
fuente
-1

Para swift 5, puede hacer simplemente así:

yourString.firstUppercased

Muestra: "abc" -> "Abc"

Hula
fuente
No hay propiedad de primera calidad en Swift
Leo Dabus