Une bibliothèque pour utiliser des cartes basées sur SVG de manière interactive dans SwiftUI.
Shape
de SwiftUINote! L'analyse SVG n'est pas encore dans sa forme finale, donc certains SVG peuvent ne pas être analysés correctement. Mais d’après ce que je peux voir, presque toutes les cartes sont dessinées correctement. Vous pouvez voir les cartes que j'ai essayées dans la section Cartes.
Les cartes sont extraites du référentiel FSInteractiveMap
Nécessite iOS 13+
InteractiveMap ne peut actuellement être installé que via Swift Package Manager.
Gestionnaire de paquets Swift Ajoutez l'URL du package : |
|
Effet d'échelle 3D
Carte effrayante
Écran de sélection de la province de Mihmandar
Pour dessiner votre carte svg dans SwiftUI, utilisez InteractiveMap
avec une fermeture prenant PathData
comme paramètre.
InteractiveMap
utilise InteractiveShape
s pour dessiner tous les chemins définis en SVG. Mais il doit savoir quel Path
sera dessiné, c'est-à-dire InteractiveMap { pathData in }
fonctionne comme ForEach { index in }
et renvoie une fermeture itérable renvoyant PathData
comme paramètre, qui contient toutes les informations sur Path
définies dans 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 se redimensionne en fonction du cadre attribué, prend tout l'espace disponible par défaut et se redimensionne de manière réactive lors des rotations de l'appareil.
Au lieu d'utiliser les attributs par défaut, vous pouvez également définir vos propres attributs.
InteractiveMap ( svgName : " tr " ) {
InteractiveShape ( $0 )
. initWithAttributes ( . init ( strokeWidth : 2 , strokeColor : . red , background : Color ( white : 0.2 ) ) )
}
Même si .initWithAttributes
permet de gagner du temps pour une simple personnalisation, il n'est ni hautement personnalisable ni modifiable.
Puisque InteractiveShape
est un Shape
, vous pouvez utiliser toutes les méthodes avec InteractiveShape
que vous pouvez utiliser avec 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
est une Struct
qui contient toutes les informations sur tous les chemins, dans notre exemple de carte, ce sont des districts et des provinces.
Il contient 5 variables. id
, path
et name
, boundingBox
et svgBounds
id
est l'identifiant unique qui est analysé directement à partir de SVG
La plupart des cartes SVG (PAS TOUS !) ont l'attribut id
dans leur élément <path>
comme ceci :
<path ... id="<id>", name="<name>">
MapParser
, défini dans MapParser.swift
analyse cet élément et les stocke dans la structure PathData
.
S'il n'y a aucun attribut id
dans le chemin, MapParser crée automatiquement une chaîne UUID.
Mais si vous souhaitez stocker cet identifiant quelque part, sachez que la chaîne UUID est automatiquement régénérée à chaque fois qu'InteractiveMap est dessiné.
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
compare essentiellement les identifiants des PathDatas.
bientôt
bientôt