DEV Community

David Goyes
David Goyes

Posted on

SwiftUI #11: Image

El componente para mostrar una imagen se llama Image. El constructor más simple (init(systemName:)) recibe el nombre de una imagen de SF symbols.

var body: some View {
  Image(systemName: "table")
}
Enter fullscreen mode Exit fullscreen mode

Cuando se crea una imagen sin modificadores, SwiftUI la pinta con su resolución nativa y mantiene su relación de aspecto.

Cambiar el tamaño de una imagen

resizable(capInsets:resizingMode:) define el modo usado por SwiftUI para cambiar el tamaño de una imagen. Recibe:

  • capInsets: Valores de relleno que indican la porción de la imagen que no se va a encuadrar.
  • resizingMode: Modo usado para encuadrar la imagen. Por defecto es Image.ResizingMode.stretch.
Image(systemName: "pencil")
  .resizable()
Enter fullscreen mode Exit fullscreen mode

Envolver una imagen en un marco

frame(width:height:alignment:) posiciona una vista dentro de un marco invisible con el tamaño especificado. Recibe:

  • width: El ancho de la vista resultante. Si width es nil, la vista resultante toma el comportamiento de tamaño de la vista de entrada.
  • height: La altura de la vista resultante. Si height es nil, la vista resultante toma el comportamiento de tamaño de la vista de entrada.
  • alignment: Alineación de la vista dentro del recuadro resultante. Aparentemente no tiene ningún efecto si el tamaño de la vista es igual al recuadro. Por defecto es center.

Al enmarcar una imagen cruda, esta conserva su tamaño original.

Image(systemName: "table")
  .frame(width: 80, height: 80)
Enter fullscreen mode Exit fullscreen mode

Hay que usar el modificador .resizable() para estirar la imagen hasta rellenar el marco.

Image(systemName: "table")
  .resizable()
  .frame(width: 80, height: 80)
Enter fullscreen mode Exit fullscreen mode

Ejercicio

Necesito que la imagen sea:

Circular

Para conseguir que la imagen sea circular se puede usar una de las dos aproximaciones:

  • La primera aplica una rectángulo con esquinas redondeadas como máscara
Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .clipShape(.rect(cornerRadius: size / 2))
Enter fullscreen mode Exit fullscreen mode
  • La segunda aplica un cículo como máscara.
Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .clipShape(Circle())
Enter fullscreen mode Exit fullscreen mode

Borde

Aunque se podría pensar en primera instancia que basta con usar el modificador border(_:width:), en realidad se estaría poniendo el borde a la imagen que tiene forma cuadrada, y no rodearíamos el círculo que usamos como máscara.

Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .clipShape(Circle())
  .border(Color.gray, width: 1)
Enter fullscreen mode Exit fullscreen mode

En lugar de border(_:width:), hay que pintar otra capa encima de la vista enmascarada con overlay(alignment:content:).

La capa que se va a pintar es un círculo.

Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .clipShape(Circle())
  .overlay {
    Circle()
  }
Enter fullscreen mode Exit fullscreen mode

En realidad no se necesita pintar un círculo encima (porque eso opacaría lo que hay detrás), sino solo el borde del mismo. Para eso, se va a usar el modificador stroke(_:style:) que pinta una línea del grosor dado alrededor de la figura dada.

Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .clipShape(Circle())
  .overlay {
    Circle().stroke(Color.gray, lineWidth: 1)
  }
Enter fullscreen mode Exit fullscreen mode

Fondo gris claro

Usar background(_:ignoresSafeAreaEdges:) para cambiar el color de fondo de la forma.

Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .clipShape(Circle())
  .overlay {
    Circle().stroke(Color.gray, lineWidth: 1)
  }
  .background(Color(white: 0.9))
Enter fullscreen mode Exit fullscreen mode

El color de fondo tomará todo el espacio disponible del recuadro, haciendo que de nuevo se vea cuadrado. Por esta razón hay que mover la máscara al final:

Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .overlay {
    Circle().stroke(Color.gray, lineWidth: 1)
  }
  .background(Color(white: 0.9))
  .clipShape(Circle())
Enter fullscreen mode Exit fullscreen mode

Pintar de rojo la imagen de la tabla

Para pintar la imagen hay que usar el modificador foregroundStyle(_:).

Image(systemName: "table")
  .resizable()
  .frame(width: size, height: size)
  .overlay {
    Circle().stroke(Color.gray, lineWidth: 1)
  }
  .background(Color(white: 0.9))
  .clipShape(Circle())
  .foregroundStyle(.red)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)