Una biblioteca para usar mapas basados en SVG de forma interactiva en SwiftUI.
Shape
de SwiftUI¡Nota! SVG Parsing aún no está en su forma final, por lo que es posible que algunos SVG no se analicen correctamente. Pero hasta donde puedo ver, casi todos los mapas están dibujados correctamente. Puedes ver los mapas que probé en la sección Mapas.
Los mapas están tomados del repositorio FSInteractiveMap.
Requiere iOS 13+
Actualmente, InteractiveMap solo se puede instalar a través del Administrador de paquetes Swift.
Administrador de paquetes rápido Agregue la URL del paquete: |
|
Efecto de escala 3D
Mapa espeluznante
Pantalla de selección de la provincia de Mihmandar
Para dibujar su mapa svg en SwiftUI, use InteractiveMap
con un cierre que tome PathData
como parámetro.
InteractiveMap
utiliza InteractiveShape
para dibujar todas las rutas definidas en SVG. Pero necesita saber qué Path
se dibujará, es decir, InteractiveMap { pathData in }
funciona igual que ForEach { index in }
y devuelve un cierre iterable que devuelve PathData
como parámetro, que contiene toda la información sobre Path
definidas dentro de svg.
import SwiftUI
import InteractiveMap
struct ContentView : View {
var body : some View {
InteractiveMap ( svgName : " tr " ) { pathData in // or just use $0
InteractiveShape ( pathData )
. initWithAttributes ( )
}
}
}
InteractiveMap cambia de tamaño según el marco asignado, ocupa todo el espacio disponible de forma predeterminada y cambia de tamaño según las rotaciones del dispositivo.
En lugar de utilizar atributos predeterminados, también puede definir sus propios atributos.
InteractiveMap ( svgName : " tr " ) {
InteractiveShape ( $0 )
. initWithAttributes ( . init ( strokeWidth : 2 , strokeColor : . red , background : Color ( white : 0.2 ) ) )
}
Aunque .initWithAttributes
ahorra tiempo para una personalización sencilla, no es altamente personalizable ni editable.
Dado que InteractiveShape
es una Shape
, puedes usar cualquier método con InteractiveShape
que puedas usar con Shape
.
InteractiveMap ( svgName : " tr " ) {
InteractiveShape ( $0 )
. stroke ( Color . cyan )
. shadow ( color : . cyan , radius : 3 , x : 0 , y : 0 )
. background ( InteractiveShape ( $0 ) . fill ( Color ( white : 0.15 ) ) )
}
PathData
es una Struct
que contiene toda la información sobre todas las rutas, en nuestro ejemplo de mapa, son distritos y provincias.
Tiene 5 variables en su interior. id
, path
y name
, boundingBox
y svgBounds
id
es el identificador único que se analiza directamente desde SVG
La mayoría de los SVG de mapas (¡NO TODOS!) tienen el atributo id
en su elemento <path>
como este:
<path ... id="<id>", name="<name>">
MapParser
, definido en MapParser.swift
analiza ese elemento y lo almacena en la estructura PathData
.
Si no hay ningún atributo id
en la ruta, MapParser crea automáticamente una cadena UUID.
Pero si va a almacenar esa identificación en algún lugar, tenga en cuenta que la cadena UUID se regenera automáticamente cada vez que se dibuja InteractiveMap.
import SwiftUI
import InteractiveMap
struct ContentView : View {
@ State private var clickedPath = PathData ( )
var body : some View {
VStack {
Text ( clickedPath . name . isEmpty ? " " : " ( clickedPath . name ) is clicked! " )
. font ( . largeTitle )
. padding ( . bottom , 15 )
InteractiveMap ( svgName : " tr " ) { pathData in // is a PathData
InteractiveShape ( pathData )
. stroke ( clickedPath == pathData ? . cyan : . red , lineWidth : 1 )
. shadow ( color : clickedPath == pathData ? . cyan : . red , radius : 3 )
. shadow ( color : clickedPath == pathData ? . cyan : . clear , radius : 3 ) // to increase the glow amount
. background ( InteractiveShape ( pathData ) . fill ( Color ( white : 0.15 ) ) ) // filling the shapes
. shadow ( color : clickedPath == pathData ? . black : . clear , radius : 5 , y : 1 ) // for depth
. onTapGesture {
clickedPath = pathData
}
. zIndex ( clickedPath == pathData ? 2 : 1 ) // this is REQUIRED because InteractiveShapes overlap, resulting in an ugly appearance
. animation ( . easeInOut ( duration : 0.3 ) , value : clickedPath )
}
}
}
}
clickedPath == pathData
básicamente compara las identificaciones de PathData.
pronto
pronto