ไลบรารีสำหรับใช้แผนที่แบบ SVG แบบโต้ตอบใน SwiftUI
Shape
ของ SwiftUI มอบให้บันทึก! การแยกวิเคราะห์ SVG ยังไม่อยู่ในรูปแบบสุดท้าย ดังนั้น SVG บางส่วนจึงอาจแยกวิเคราะห์ไม่ถูกต้อง แต่เท่าที่ผมเห็นเกือบทุกแผนที่ถูกวาดอย่างถูกต้อง คุณสามารถดูแผนที่ที่ฉันลองใช้ได้ในส่วนแผนที่
แผนที่นำมาจาก FSInteractiveMap Repository
ต้องใช้ iOS 13+
ปัจจุบัน InteractiveMap สามารถติดตั้งผ่าน Swift Package Manager เท่านั้น
ผู้จัดการแพ็คเกจ Swift เพิ่ม URL แพ็คเกจ: |
|
เอฟเฟกต์การปรับขนาด 3D
แผนที่น่าขนลุก
หน้าจอการเลือกจังหวัด Mihmandar
หากต้องการวาดแผนที่ svg ของคุณใน SwiftUI ให้ใช้ InteractiveMap
โดยปิดโดยใช้ PathData
เป็นพารามิเตอร์
InteractiveMap
ใช้ InteractiveShape
เพื่อวาดเส้นทางทั้งหมดที่กำหนดไว้ใน SVG แต่จำเป็นต้องรู้ว่า Path
ใดที่จะถูกวาด นั่นคือ InteractiveMap { pathData in }
ทำงานเหมือนกับ ForEach { index in }
และส่งคืนการปิดแบบวนซ้ำได้ โดยส่งคืน PathData
เป็นพารามิเตอร์ ซึ่งมีข้อมูลทั้งหมดเกี่ยวกับ Path
ที่กำหนดไว้ภายใน 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 ปรับขนาดตัวเองเป็นเฟรมที่กำหนด ใช้พื้นที่ว่างทั้งหมดตามค่าเริ่มต้น และปรับขนาดตัวเองตามการหมุนอุปกรณ์
แทนที่จะใช้แอตทริบิวต์เริ่มต้น คุณสามารถกำหนดแอตทริบิวต์ของคุณเองได้เช่นกัน
InteractiveMap ( svgName : " tr " ) {
InteractiveShape ( $0 )
. initWithAttributes ( . init ( strokeWidth : 2 , strokeColor : . red , background : Color ( white : 0.2 ) ) )
}
แม้ว่า .initWithAttributes
จะช่วยประหยัดเวลาในการปรับแต่งแบบง่ายๆ แต่ก็ไม่สามารถปรับแต่งหรือแก้ไขได้ในระดับสูง
เนื่องจาก InteractiveShape
เป็น Shape
คุณสามารถใช้วิธีการใดๆ กับ InteractiveShape
ที่คุณสามารถใช้กับ 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
เป็น Struct
ที่ประกอบด้วยข้อมูลทั้งหมดเกี่ยวกับเส้นทางทั้งหมด ในตัวอย่างแผนที่ของเรา ได้แก่ เขตและจังหวัด
มี 5 ตัวแปรอยู่ข้างใน id
, path
และ name
, boundingBox
และ svgBounds
id
คือ Unique Identifier ที่ถูกแยกวิเคราะห์โดยตรงจาก SVG
Map SVG ส่วนใหญ่ (ไม่ใช่ทั้งหมด!) มีแอตทริบิวต์ id
ทั้งหมดอยู่ในองค์ประกอบ <path>
ดังนี้:
<path ... id="<id>", name="<name>">
MapParser
ที่กำหนดไว้ใน MapParser.swift
แยกวิเคราะห์องค์ประกอบนั้นและเก็บไว้ในโครงสร้าง PathData
หากไม่มีแอตทริบิวต์ id
ใด ๆ ในเส้นทาง MapParser จะสร้างสตริง UUID โดยอัตโนมัติ
แต่ถ้าคุณจะเก็บ id นั้นไว้ที่ใดที่หนึ่ง โปรดทราบว่า UUID String จะถูกสร้างขึ้นใหม่โดยอัตโนมัติทุกครั้งที่มีการวาด 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
โดยพื้นฐานแล้วจะเปรียบเทียบ id ของ PathDatas
เร็วๆ นี้
เร็วๆ นี้