lunes, 20 de octubre de 2014

Swift y TextView

        
Asignar atributos en un TextView

En el caso de querer modificar una porción  de texto dentro de un UITextView . 

UIFontDescriptor proporciona un mecanismo para describir un tipo de letra con  un diccionario de atributos.

let bodyFontDescriptor = UIFontDescriptor.preferredFontDescriptorWithTextStyle(UIFontTextStyleBody)
textView.font = UIFont(descriptor: bodyFontDescriptor, size: 0)


 let attributedText = NSMutableAttributedString(attributedString: textView.attributedText!)

 let text = textView.text! as NSString

        

 // El texto "Contenido" forma parte del texto del textView.text = "Contenido del componente" let textoVerde = text.rangeOfString(NSLocalizedString("Contenido", comment: ""))         // Aplicamos un estilo declarado con un fondo verde y se aplica al rango textoVerde attributedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.applicationGreenColor(), range: textoVerde)        

 // Actualizamos el attributed Text textView.attributedText = attributedText

lunes, 13 de octubre de 2014

Swift y Tipos Genéricos (Generics)


Generic es una característica de Swift que te permite reutilizar funciones.
Un tipo Array y Dictionary son colecciones de genéricos. 
Puedes crear una Array que contenga tipos Int, String u otro tipo, igual pasa con los Dictionary.
En el caso de tener una struct que contenga un Array de tipo String, con un método poner y quitar.

struct ContenidoString{
   var valores: String [];
       mutating func poner(x: String){
            valores += x
        }

      mutating func quitar() -> String {
          return valores.removelast()
      }
}

Para que esta struct sea genérica
struct Contenido <T> {
 var valores: T [];
       mutating func poner(x: T){
            valores += x
        }

      mutating func quitar() -> T {
          return valores.removelast()
      }
}

Utilización :
var contenidoEnteros = Contenido<Int>()
contenidoEnteros.poner(100)
var contenidoEnteros = Contenido<String>()
contenidoEnteros.poner(@"100")








jueves, 9 de octubre de 2014

Swift y Extensiones (Extensions)

Extensions añade nuevas funcionalidades a una clase existente, structure or un tipo enumeration.

Se declaran con la palabra clave extension.

extension NombreTipo {

  // nuevas funcionalidades a añadir

}

extension puede extender un tipo para que adopte uno más protocolos.

extension NombreTipo: ProtocoloUno, ProtocoloDos {

   // implementación de los protocolos requeridos van aquí

}


Si se define una extension para añadir nuevas funcionalidades a un tipo existente, la nueva funcionalidad estará disponible para todas las instancias existentes de ese tipo.


Propiedades Calculadas

En este ejemplo se añaden cuatro propiedades calculadas. Nuevas propiedades que multiplica por 2 y suma 2, multiplica por tres y suma 3 al valor indicado.

extension Double {

   var porDos: Double 

             return self * 2 
      }

   var masDos: Double { 

              return self + 2  
     }

   var porTres: Double { 

              return self * 3 
    }

   var masTres: Double { 

             return self + 3 
   }

}


10.2 es un double que puede obtener esas propiedades calculadas.

let valorPorDos = 10.2.porDos

println("10.2 * 2 =  \(valorPorDos)")

// Imprimirá 10.2 * 2 =  20.4


let valorPorTres = 10.2.porTres

println("10.3 * 3 =  \(valorPorTres)")

// Imprimirá 10.3 *32 =  30.9


También es posible realizar operaciones matemáticas.

let sumaValores = 1.0.porDos + 1.0.porTres

El resultado de suma varlores será de 5 ya que (1 * 2 + 1 * 3 = 5 )


Inicializaciones

extension pueden añadir inicializaciones a tipo existentes.

struct Distancia {
     var metros = 0.0
}

struct Temperatura {
    var grados = 0.0
}


struct Ciudad {
  
   var distancia = Distancia()
  
  var temperatura = Temperatura()

}


Se puede extender la estructura Ciudad para indicar valores de inicialización.


extension Ciudad {

     init(distanciaIn: Distancia, temperaturaIn: Temperatura) {
      
      // se calculan valores temporales
       let distanciaKm = distanciaIn.metros * 1000;
       let temperaturaMasUno =  temperaturaIn.grados + 1;

      // para después inicializar
      self.init(distancia: Distancia(metros:distanciaKm),
                                           temperatura: temperaturaMasUno)

      }
}











miércoles, 8 de octubre de 2014

Swift y Protocolos (Protocols)

Swift y Protocolos (Protocols)

Un protocolo define métodos, propiedades y otros requerimientos que debe ser  implementados en las clases que los adopten en su definición.

El protocolo no contiene implementación. 

El protocolo puede ser adaptado por una clase, structure o enumeration,  para que implemente los requerimientos indicados por el protocolo.

Definir un Protocolo

protocol PrimerProtocolo {
   // contenido del protocolo
}


Para que un tipo definido adopte un protocolo escribir el nombre del protocolo después del nombre del tipo separado por una coma

Varios protocolos pueden ser incluidos separados por una coma.

struct Informacion: PrimerProtocolo, SegundoProtocolo {

  // en este caso implementará los requerimientos de los dos protocols

}

Si la clase hereda de una superclase, el nombre de la superclase tiene que estar delante de cualquier nombre de protocolo

class ClaseUno: SuperClase , PrimerProtocolo, SegundoProtocolo {

}

Propiedades Requeridas

Solo especifica el nombre y el tipo.

El protocolo también especifica cuando cada propiedad debe de ser gettable or gettable y settable.

Las propiedades son siempre declaradas como variables con el prefijo var.

Gettable y settable se indican con { get set } después de declarar el tipo, y el Gettable se indica escribiendo { get }

protocol PrimerProtocolo {

  var debeDeSerSetteable: Int { get set }

 var noDebeSerSetteable: Int { get }

}

Un ejemplo  de un protocolo con una simple instancia propiedad.

protocol MarcaModelo {
   var marcaModelo: String { get }
}

Ejemplo de una simple estructura que adopta el protocolo MarcaModelo.

struct Coche: MarcaModelo {
   var marcaModelo: String
}

let miCoche = Coche(marcaModelo: "Seat")

// miCoche.marcaModelo contiene "Seat"

Cada instancia de Coche tiene una propiedad llamada marcaModelo, que es de tipo String.



Un ejemplo que adopta el protocolo MarcaModelo.


class CocheInformacion: MarcaModelo{

  var cilindrada: String ?
  var nombre: String

 // método de inicialización

  init(nombre: String, cilindrada: String ? = nil) {

    self.nombre = nombre
    self.cilindrada = cilindrada

 }

 // establecer el contenido de marcaModelo

 var marcaModelo: String {

    return (cilindrada != nil ? cilindrada ! + ":") + nombre

 }

}

// ****************  Final de la definición de CocheInformacion



Cada CocheInformacion almacena un atributo nombre obligatorio y un opcional llamado cilindrada.

marcaModelo utilizar cilindrada si el valor existe.

var miCoche = CocheInformacion(nombre: "Seat", cilindrada: "120cc")

Ahora  miCoche.marcaModelo contiene "120cc Seat"


Próximo contenido: Métodos Requeridos




martes, 7 de octubre de 2014

Swift y las Funciones (Functions)

Swift y las Funciones (Functions)

Las funciones son contenedores de código independientes que ejecutan una tarea específica.

Los parámetros que reciben las funciones pueden contener valores por defecto para simplificar la llamada a las funciones, y pueden ser pasadas como in-out, serán modificadas las variables pasadas una vez que se haya finalizado la ejecución de la función.

func mostrarMensaje(mensajeIn: String) -> String {

 let contenidoRetorno = "Cadena inicial " + mensajeIn

 return contenidoRetorno
}

Se indica el valor de retorno mediante un guión y el símbolo mayor que (->) seguido por el tipo a retornar.

Utilizando la llamada en un println:

println(mostrarMensaje("final de la cadena"))


Parámetros y Valores de Retorno en las Funciones

Las funciones pueden tener múltiples parámetros de entrada, que son escritos dentro de unos paréntesis, separados por comas.

func sumaNumeros(primero: Int, segundo: Int) -> Int {

 return primero + segundo;

}

println(sumaNumeros(39,19));


Las funciones pueden no recibir parámetros.

func sumaNumeros100_200() -> String {

   return 100 + 200

}

println(sumaNumeros())

Las funciones pueden no retornar valores. En este caso no incluiremos ( -> ) ni el tipo de retorno.

func mostrarMensajeAviso(mensajeIn: String){

  println("Aviso : \(mensajeIn)")

}

Funciones Con Múltiples Valores de Retorno

Se puede utilizar un tipo Tuple  como valor de retorno para que una función devuelva múltiples valores.

func valoresSuma(arrayIn: [Int]) -> (elementos: Int, total: Int){

        var suma = 0

        for value in arrayIn[1..<arrayIn.count]
        {
               suma += value
        }

  return (arrayIn.count, suma)

}

La utilización de esta función para mostrar los valores retornados.

let valores = valoresSuma([1,2,3,4],100)

println("valores en array \(valores.elementos) y el total suma mas cien \(valores.total)")


Tuple Opcionales como Retorno


Se puede utilizar un opcional tiple como retorno tipo para indicar que el contenido tuple puede ser nil.

Indicar un opcional tuple como tipo de retorno

(Int, Int)?
(String, Int, Bool)?

func valoresSuma(arrayIn: [Int]) -> (elementos: Int, total: Int)? {

 if arrayIn.isEmpty { return nil }

  var suma = 0

  for value in arrayIn[1..<arrayIn.count]
 {
     suma += value
 }

  return (arrayIn.count, suma)

}


Nombre de Parámetros en las Funciones


Las funciones definen nombres a los parámetros.

func nombreFuncion(nombreParametro: Int){
    // Contenido de la función
}

Estos nombre de parámetros son utilizados dentro de la función. Esta clase de parámetros son conocidos como parámetros locales, porque son sólo disponibles dentro de la función.


Nombre de Parámetros Externos

A veces es útil nombrar a los parámetros cuando se llama a un función, para indicar el propósito de cada argumento que se pasa a la función.

Declarar un nombre de parámetro externo además del parámetro local.

func sumaNumeros(valorNumerico cifra: Int) {

 // el nombre del parámetro local es cifra, y el externo valorNumerico

}

La llamada a esta función será : sumaNumeros(valorNumerico: 233)

Para una función que reciba tres parámetros

func ganadores(primero: String, segundo: String,  tercero: String) -> String {

 return ("1 : \(primero) 2: \(segundo) 3:\(tercero)")

}

la llamada a esta función será

ganadores("josé","juan","edu")

Para una lectura mejor de código

func ganadores(Oro primero: String
         Plata segundo: String,  Bronce tercero: String) -> String {

 return ("1 : \(primero) 2: \(segundo) 3:\(tercero)")

}

Y la llamada con estos nombre de parámetros externos será.

ganadores(Oro:"josé", Plata:"juan", Broce:"edu")

De esta manera la diferencia con la versión anterior ganadores("josé","juan","edu") es mucha más clara a la hora de leer el código.

Utilizar el Nombre del Parámetro local

En el caso de que el nombre de parámetro local sea válido para una clara lectura del código utilizar el símbolo hash (#) y no será necesario declarar ningún nombre externo


func ganadores(#primero: String, #segundo: String,  #tercero: String) -> String {

 return ("1 : \(primero) 2: \(segundo) 3:\(tercero)")

}

La llamada de la función será

ganadores(primero:"josé",segundo:"juan",tercero:"edu")


Valores por Defecto en los Parámetros

Se puede definir valores por defecto en los parámetros. 
Si se define un valor por defecto se puede omitir el parámetro en la llamada.

func ganadores(#primero: String, #segundo: String
                                #tercero: String = " sin adjudicar ") -> String {

 return ("1 : \(primero) 2: \(segundo) 3:\(tercero)")

}

La llamada a esta función sin incluir el parámetro con valor por defecto.

ganadores(primero:"josé", segundo:"juan")