מידע על Codelab זה
1. לפני שתתחיל
ב-Codelab הזה אנחנו מסבירים איך להתחיל להשתמש באפליקציות של מפות Google לבניית אפליקציות ל-iOS ב-Swift. תיווצר אפליקציה ל-iOS שמבצעת את הפעולות הבאות:
- טוענת את ה-SDK של מפות Google ל-iOS ואת ה-SDK של מפות Google לספריית התשתיות ל-iOS.
- מוצגת מפה שבמרכזה סידני, אוסטרליה.
- הצגת סמנים מותאמים אישית ל-100 נקודות מסביב לסידני.
- מטמיע אשכולות סמנים.
- מאפשר אינטראקציה של משתמש שמתרכז במרכז מחדש ומציירים עיגול במפה כשמקישים על סמן.
דרישות מוקדמות
- ידע בסיסי על פיתוח של Swift ו-iOS.
מה תלמדו
- המערכת טוענת את ה-SDK של מפות Google ל-iOS ואת ה-SDK של מפות Google לספריית כלי השירות ל-iOS.
- המפה נטענת.
- שימוש בסמנים, בסמנים מותאמים אישית ובאשכולות של סמנים.
- עבודה עם מערכת ה-SDK של מפות Google ל-iOS כדי לספק אינטראקציה למשתמשים.
- שליטה במצלמת המפה באופן פרוגרמטי.
- ציור על המפה.
מה תצטרך להכין
כדי להשלים את ה-Codelab הזה צריך את החשבונות, השירותים והכלים הבאים:
- Xcode 12.0 ואילך עם יעד SDK מגרסה 12.0 ואילך
- Cocoapods הותקנו.
- חשבון ב-Google Cloud Platform שהחיוב מופעל בו (ראו את השלב הבא).
- פרויקט ב-Cloud Console עם ה-SDK של מפות Google ל-iOS (ראו השלב הבא).
2. להגדרה
בשלב ההפעלה שבהמשך, עליכם להפעיל את SDK של מפות Google ל-iOS.
הגדרת מפות Google
אם עדיין אין לכם חשבון Google Cloud Platform ופרויקט שבו מופעל חיוב, כדאי לעיין במדריך תחילת העבודה עם הפלטפורמה של מפות Google ליצירת חשבון לחיוב ופרויקט.
- ב-Cloud Console, לוחצים על התפריט הנפתח של הפרויקט ובוחרים את הפרויקט שבו רוצים להשתמש ב-Codelab הזה.
- מפעילים את ממשקי ה-API ואת ערכות ה-SDK של מפות Google הנדרשים למעבדת קוד זו ב-Google Cloud Marketplace. כדי לעשות זאת, יש לבצע את השלבים המפורטים בסרטון הזה או בתיעוד הזה.
- יוצרים מפתח API בדף פרטי הכניסה ב-Cloud Console. ניתן לבצע את השלבים המפורטים בסרטון הזה או בתיעוד הזה. לכל הבקשות שנשלחות לפלטפורמה של מפות Google נדרש מפתח API.
מדריך למתחילים
כדי לעזור לך להתחיל במהירות האפשרית, לפניך קוד התחלה שיעזור לך לעקוב אחר שיעור Lab זה.
- משכפלים את המאגר אם
git
מותקן.
git clone https://github.com/googlemaps/codelab-maps-platform-101-swift.git
לחלופין, לוחצים על אני רוצה לקבל את הקוד כדי להוריד את קוד המקור.
- לאחר הורדת הקוד, יש לפתוח את הפרויקט StarterApp בספרייה
/starter
. הפרויקט כולל את מבנה הקבצים הבסיסי הדרוש כדי להשלים את Lablab. כל מה שצריך לעבוד נמצא בספרייה של/starter/StarterApp
.
כדי להציג את קוד הפתרון המלא, יש להציג את הקוד המלא בספרייה /solution/SolutionApp
.
3. התקנת SDK של מפות ל-iOS
השלב הראשון בשימוש ב-SDK של מפות Google ל-iOS הוא להתקין את תלויות תלויות. יש שני שלבים בתהליך הזה: התקנת ה-SDK של מפות Google ל-iOS וה-SDK של מפות Google ל-iOS ככלי עזר ממנהל התלות של Cocoapods, והעברת מפתח ה-API ל-SDK.
- מוסיפים את ה-SDK של מפות Google ל-iOS ול-Maps SDK עבור ספריית השירותים של iOS אל
Podfile
.
ב-codelab זה נעשה שימוש ב-SDK של מפות Google ל-iOS, שמספק את כל הפונקציות המרכזיות של מפות Google, וגם בספריית השירות של מפות iOS ל-iOS, המספקת מגוון שירותים להעשרה של המפות שלכם, כולל אשכול סמנים.
כדי להתחיל, ב-Xcode (או בעורך הטקסט המועדף עליכם) פותחים את Podfile
ומעדכנים את הקובץ כך שיכלול את ה-SDK של מפות Google ל-iOS ולתלויות בספריית השירות מתחת לתגובה # Pods for StarterApp
:
pod 'GoogleMaps', '6.1.0'
pod 'Google-Maps-iOS-Utils', '3.4.0'
כדי לקבל מידע בנוגע לגרסה העדכנית ביותר של ה-SDK, ולקבל הוראות לתחזוקה, יש לבדוק את התיעוד של מפות Google ל-Versions ב-iOS.
ה-Podfile
אמור להיראות כך:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '12.0'
target 'StarterApp' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for StarterApp
pod 'GoogleMaps', '6.1.0'
pod 'Google-Maps-iOS-Utils', '3.4.0'
end
- מתקינים את ה-SDK של מפות Google ל-iOS ואת ה-SDK של מפות Google ל-iOS Pod SDK.
כדי להתקין את תלויות, יש להריץ את pod install
בספרייה /starter
משורת הפקודה. Cocoapods מורידה באופן אוטומטי את התלות ויוצרת StarterApp.xcworkspace
.
- לאחר שהתלויות מותקנות, יש להריץ את
open StarterApp.xcworkspace
מספריית/starter
כדי לפתוח את הקובץ ב-Xcode, ואז להפעיל את האפליקציה בסימולטור iPhone על ידי הקשה עלCommand+R
. אם כל הפרטים מוגדרים כראוי, הסימולטור יופעל ויציג מסך שחור. אל דאגה, עדיין לא יצרת שום דבר, כך זה צפוי! - מייבאים את ה-SDK ב-
AppDelegate.swift
.
עכשיו, בהתאם לתלויות שלכם, הגיע הזמן לספק את מפתח ה-API ל-SDK. השלב הראשון הוא לייבא את ה-SDK של מפות Google ל-iOS כפונקציה על ידי הוספת הערכים הבאים מתחת להצהרת הייבוא import UIKit
:
import GoogleMaps
- יש להעביר את מפתח ה-API ל-iOS SDK באמצעות התקשרות אל
provideAPIKey
ברחובGMSServices
בapplication: didFinishLaunchingWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
GMSServices.provideAPIKey("YOUR_API_KEY")
return true
}
עכשיו קובץ ה-AppDelegate.swift
המעודכן אמור להיראות כך:
import UIKit
import GoogleMaps
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
GMSServices.provideAPIKey("YOUR_API_KEY")
return true
}
}
מחליפים את YOUR_API_KEY
במפתח ה-API שיצרתם ב-Cloud Console.
עכשיו, בהתאם לתלויות שלכם ומפתח ה-API שלכם מוכן, תוכלו להתחיל להתקשר ל-SDK של מפות Google ל-iOS.
4. הצגת מפה
הגיע הזמן להציג את המפה הראשונה שלך!
החלק הנפוץ ביותר ב-SDK של מפות Google ל-iOS הוא הכיתה GMSMapView
, שמספקת שיטות רבות שמאפשרות ליצור מופעים של מפות ולשנות אותם. ככה זה עובד.
- פתיחת
ViewController.swift
כאן תעשו את שאר העבודה במסגרת מעבדת קוד זו. חשוב לדעת ש-loadView
ו-viewDidLoad
אירועים במחזור החיים של בקר התצוגה כבר לא זמינים.
- ניתן לייבא את ה-SDK של מפות Google ל-iOS על ידי הוספת הפרמטר הזה בחלק העליון של הקובץ:
import GoogleMaps
- יש לציין משתנה מופע אחד (
ViewController
) כדי לאחסן אתGMSMapView
.
המופע של GMSMapView
הוא האובייקט העיקרי שאיתו אתם עובדים ב-codelab זה. עליכם להתייחס אליו ולפעול משיטות מחזור החיים השונות של בקר התצוגה. כדי להפוך אותו לזמין, יש לעדכן את ההטמעה של ViewController
כדי להצהיר על משתנה מכונה כדי לאחסן אותו:
class ViewController: UIViewController {
private var mapView: GMSMapView!
...
}
- ב-
loadView
, יוצרים מכונה שלGMSCameraPosition
.
GMSCameraPosition
מגדיר את המיקום המרכזי של המפה ואת רמת הזום שמוצגת. קוד זה קורא לשיטה cameraWithLatitude:longitude:zoom:
כדי למרכז את המפה בסידני, אוסטרליה, בקו רוחב של -33.86 וקו האורך של 151.20, עם רמת זום של 12:
let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 12)
- ב-
loadView
, יש ליצור מופע שלGMSMapView
כדי ליצור את המפה מיד.
כדי ליצור מופע מפה חדש יש להתקשר אל GMSMapView(frame: CGRect, camera: GMSCameraPosition)
. שימו לב שהמסגרת מוגדרת ל-CGRect.zero
, שהוא משתנה גלובלי מספריית CGGeometry
ב-iOS . הוא מציין מסגרת של 0 רוחב, 0 גובה, ממוקם במיקום (0,0) בתוך בקר התצוגה. המצלמה מוגדרת למיקום המצלמה שיצרתם.
לאחר מכן, כדי להציג את המפה, צריך להגדיר את תצוגת הבסיס של בקר התצוגה כך: mapView
, כך שהמפה תוצג במסך מלא.
mapView = GMSMapView(frame: .zero, camera: camera)
self.view = mapView
- הגדרת
GMSMapViewDelegate
לבקר התצוגה.
לאחר ההטמעה, מי שנתת לו תצוגת מפה יוכל לטפל באירועים מאינטראקציות של המשתמשים במופע של GMSMapView
, הנדרש לך מאוחר יותר.
תחילה, יש לעדכן את הממשק של ViewController
כך שיתאים לפרוטוקול של GMSMapViewDelegate:
class ViewController: UIViewController, GMSMapViewDelegate
עכשיו צריך להוסיף את הפונקציה הזו לפונקציה loadView
כדי להגדיר את GMSMapViewDelegate
לערך ViewController
.
mapView.delegate = self
עכשיו טוענים מחדש את האפליקציה בסימולטור iOS (Command+R
) והמפה אמורה להופיע באיור 1.
איור 1. אפליקציית iOS מציגה מפה של Google.
לסיכום, בשלב זה יצרת מופע של GMSMapView
להצגת מפה שבמרכזה העיר סידני, אוסטרליה.
עכשיו קובץ ה-ViewController.swift
אמור להיראות כך:
import UIKit
import GoogleMaps
class ViewController: UIViewController, GMSMapViewDelegate {
private var mapView: GMSMapView!
override func loadView() {
// Load the map at set latitude/longitude and zoom level
let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 11)
mapView = GMSMapView(frame: .zero, camera: camera)
self.view = mapView
mapView.delegate = self
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
5. עיצוב המפה (אופציונלי)
אפשר להתאים אישית את סגנון המפה באמצעות סגנון המפה המבוסס על ענן.
יצירת מזהה מפה
אם עדיין לא יצרתם מזהה מפה שמשויכים אליו סגנון מפה, תוכלו להיעזר במדריך מזהי מפות כדי:
- יוצרים מזהה מפה.
- משייכים מזהה מפה לסגנון מפה.
הוספת מזהה המפה לאפליקציה שלך
כדי להשתמש במזהה המפה שיצרת בשלב הקודם, יש לפתוח את הקובץ ViewController.swift
ובשיטה loadView
ליצור אובייקט GMSMapID
ולספק לו את מזהה המפה. בשלב הבא, מגדירים את האובייקט GMSMapID
ב-GMSMapView
כפרמטר ומשנים את האובייקט.
ViewController.swift
override func loadView() {
// Load the map at set latitude/longitude and zoom level
let camera:GMSCameraPosition = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 11)
let mapID = GMSMapID(identifier: "YOUR_MAP_ID")
mapView = GMSMapView(frame: .zero, mapID: mapID, camera: camera)
self.view = mapView
mapView.delegate = self
}
אחרי שמסיימים, מפעילים את האפליקציה כדי לראות את המפה בסגנון שבחרתם.
6. הוספת סמנים למפה
יש הרבה דברים שמפתחים עושים עם ה-SDK של מפות ל-iOS, אבל הוספה של סמנים למפה היא בהחלט הפופולרית ביותר. סמנים מציגים נקודות ספציפיות במפה, וזהו רכיב נפוץ לטיפול באינטראקציה של משתמש. אם השתמשתם בעבר במפות Google, סביר להניח שאתם מכירים את סמן ברירת המחדל, שנראה כמו הסיכות האדומות באיור 2:
איור 2. מפה עם סמנים אדומים.
שלב זה מדגים איך להשתמש בכיתה GMSMarker
כדי להציב סמנים במפה.
לתשומת ליבך: לא ניתן למקם סמנים במפה עד לטעינת המפה מהשלב הקודם באירוע מחזור החיים של loadView
בבקר התצוגה, לכן יש להשלים את השלבים האלה באירוע מחזור החיים של viewDidLoad
, הנקרא אחרי שהתצוגה (והמפה) נטענו.
- הגדרה של אובייקט
CLLocationCoordinate2D
.
CLLocationCoordinate2D
הוא מבנה הזמין על ידי ספריית CoreLocation ב-iOS, שמגדיר מיקום גיאוגרפי בקו רוחב וקו אורך. כדי להתחיל ליצור את הסמן הראשון, יש להגדיר אובייקט CLLocationCoordinate2D
ולהגדיר את קווי הרוחב והאורך במרכז המפה. ניתן לגשת לקואורדינטות של מרכז המפה מתצוגת המפה באמצעות הנכסים camera.target.latitude
ו-camera.target.longitude
.
// Add a single marker with a custom icon
let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
- יצירת מכונה של
GMSMarker
.
ה-SDK של מפות Google ל-iOS מספק את המחלקה GMSMarker
. כל מופע של GMSMarker
מייצג סמן ספציפי במפה, שנוצר על ידי קריאה ל-markerWithPosition:
והעברתו לאובייקט CLLocationCoordinate2D
כדי לומר ל-SDK איפה להציב את הסמן במפה.
let marker = GMSMarker(position: mapCenter)
- הגדרה של סמל סמן בהתאמה אישית.
סמן הסיכה האדום המוגדר כברירת מחדל עבור מפות Google הוא נהדר, אבל זו גם ההתאמה האישית של המפה שלך! למזלנו, קל מאוד להשתמש בסמן מותאם אישית באמצעות ה-SDK של מפות Google ל-iOS. שימו לב שפרויקט StarterApp כולל תמונה בשם 'custom_pin.png'', כדי שתוכלו להשתמש בה בכל תמונה שתרצו.
כדי להגדיר את הסמן המותאם אישית, צריך להגדיר את מאפיין icon
של הסמן למופע של UIImage
.
marker.icon = UIImage(named: "custom_pin.png")
- מעבד את הסמן במפה.
הסמן נוצר, אך הוא עדיין לא מופיע במפה. לשם כך, יש להגדיר את המאפיין map
במופע של GMSMarker
למופע של GMSMapView
.
marker.map = mapView
עכשיו טוענים מחדש את האפליקציה ומעריכים את המפה הראשונה באמצעות סמן כפי שמופיע באיור 3!
איור 3. אפליקציה ל-iOS עם סמן מפות Google בסמן אדום במרכזה.
לסיכום, בקטע הזה יצרת מופע של הכיתה של GMSMarker והחלת אותו על תצוגת המפה כדי להציג סמן במפה. אירוע מחזור החיים המעודכן ב-viewDOLoad ב-ViewController.swift
אמור להיראות כך:
override func viewDidLoad() {
super.viewDidLoad()
// Add a single marker with a custom icon
let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
let marker = GMSMarker(position: mapCenter)
marker.icon = UIImage(named: "custom_pin.png")
marker.map = mapView
}
7. הפעלה של אשכול סמן
אם אתם משתמשים בסמנים רבים או אם יש לכם סמנים שקרובים זה לזה, ייתכן שתיתקלו בבעיה שבה הסמנים חופפים או שהם מקובצים יחד. מצב כזה יוצר חוויית משתמש שלילית. לדוגמה, אם שני סמנים קרובים מאוד, עלולים להיווצר מצב כפי שמוצג באיור 4:
איור 4. שני סמנים קרובים מאוד.
כאן אשכול הסימונים. אשכולות סמנים הם תכונה נוספת שמיושמת בדרך כלל, ומקבצת סמנים בקרבת מקום לסמל אחד שמשתנה בהתאם לרמת הזום, כמו באיור 5:
איור 5. דוגמאות לסמנים שמקובצים יחד לסמל אחד.
האלגוריתם לאשכול סמנים מחלק את האזור הגלוי במפה למפה, ולאחר מכן מקבצים סמלים שנמצאים באותו תא. הצוות של מפות Google יצר ספרייה שימושית בקוד פתוח בשם 'מפות Google עבור SDK ל-iOS', הכוללת, בין היתר, אשכול של סמנים באופן אוטומטי. אפשר לקרוא מידע נוסף על אשכול סמנים בתיעוד של הפלטפורמה של מפות Google או לקרוא את המקור של ספריית השירותים של iOS ב-GitHub.
- אפשר להוסיף למפה הרבה יותר סמנים.
כדי לראות אשכול של סמנים בפעולה, אתם צריכים לכלול הרבה סמנים במפה. כדי להקל על התהליך, מסופק לכם מחולל סמן נוח בפרויקט למתחילים ב-MarkerGenerator.swift
.
כדי להוסיף מספר סמנים ספציפי למפה, יש להתקשר אל MarkerGenerator(near:count:).markerArray
במחזור החיים של הבקר והתצוגה המפורטת viewDidLoad
מתחת לקוד מהשלב הקודם. השיטה יוצרת את מספר הסמנים שצוינו ב-count
במיקומים אקראיים מסביב לקואורדינטות שצוינו באובייקט CLLocationCoordinate2D
. במקרה כזה, אפשר להעביר אותו למשתנה mapCenter
שיצרת קודם. הסימונים מוחזרים ב-[GMSMarker]
.
// Generate many markers
let markerArray = MarkerGenerator(near: mapCenter, count: 100).markerArray
כדי לבדוק איך הסימנים האלה נראים, יש להוסיף את השורות האלה אחרי ההגדרה של markerArray
ואז להריץ את האפליקציה. חשוב להקפיד לסמן את השורות האלה לפני שממשיכים לשלבים הבאים, שבהם נעשה שימוש באשכול הסמן כדי לנהל את התצוגה של הסמנים:
// Comment the following code out if using the marker clusterer
// to manage markers instead.
for marker in markerArray {
marker.map = mapView
}
- מייבאים את ה-SDK של מפות Google לספריית התשתיות של iOS.
כדי להוסיף את ספריית השירותים של iOS ל-iOS כתלויה בפרויקט שלכם, יש להוסיף אותה לרשימת התלות בחלק העליון של ViewController.swift
:
import GoogleMapsUtils
- הגדרת אשכול הסמן.
כדי להשתמש באשכולת הסמן, עליך לספק שלושה דברים כדי להגדיר את אופן הפעולה שלהם: אלגוריתם אשכול, מחולל סמלים ומעבד. האלגוריתם קובע את אופן קיבוץ הסימונים, למשל המרחק בין הסמנים להכללה באותו אשכול. מחולל הסמלים מספק את סמלי האשכול לשימוש ברמות זום שונות. כלי הרינדור מטפל ברינדור בפועל של סמלי האשכול במפה.
תוכלו לכתוב את כל השלבים האלה אם תרצו, אבל ספריית כלי הניהול של מפות Google ל-iOS מספקת הטמעות ברירת מחדל כדי להקל על התהליך. הוספה:
// Set up the cluster manager with a supplied icon generator and renderer.
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let iconGenerator = GMUDefaultClusterIconGenerator()
let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
- יצירת מכונה של
GMUClusterManager
.
GMUClusterManager
היא המחלקה שמטמיעה מקבצים של סימנים באמצעות האלגוריתם, מחולל הסמלים והמעבד שצוין על ידך. כדי ליצור את כלי הרינדור ולהפוך אותו לזמין לתצוגת המפה, תחילה יש להוסיף משתנה מופע להטמעה של ViewController
כדי לאחסן את המופע של מנהל האשכול.
class ViewController: UIViewController, GMSMapViewDelegate {
private var mapView: GMSMapView!
private var clusterManager: GMUClusterManager!
}
לאחר מכן, יוצרים את המופע של GMUClusterManager
באירוע מחזור החיים של viewDidLoad
:
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
- מוסיפים את הסמנים ומפעילים את אשכול הסמן.
עכשיו, לאחר שהגדרת מופע של אשכול סמן, יש להעביר את מנהל האשכולות למקבץ של אשכולות על ידי קריאה ל-add(items:)
. לאחר מכן, יש להריץ את הפונקציה מקבץ ההתראות באמצעות קריאה ל-cluster
.
clusterManager.setMapDelegate(self)
clusterManager.add(markerArray)
clusterManager.cluster()
טוענים מחדש את האפליקציה, ועכשיו אמורים לראות הרבה סמנים שמקובצים בצורה יפה, כמו בדוגמה באיור 6. אפשר להתקדם ולשחק עם רמות זום שונות על ידי תנועת צביטה ושינוי המרחק מהתצוגה במפה, כדי לראות את אשכולות הסמן כשמגדילים או מקטינים.
איור 6. אפליקציית iOS עם מפות Google וסמנים מקובצים.
לסיכום, בשלב זה הגדרתם מופע של אשכול הסימונים מה-SDK של מפות Google ל-iOS Utility Directory, ולאחר מכן השתמשתם בו כדי לקבץ 100 סמנים במפה. אירוע מחזור החיים של viewDidLoad
בViewController.swift
אמור להיראות כך:
override func viewDidLoad() {
super.viewDidLoad()
// Add a single marker with a custom icon
let mapCenter = CLLocationCoordinate2DMake(mapView.camera.target.latitude, mapView.camera.target.longitude)
let marker = GMSMarker(position: mapCenter)
marker.icon = UIImage(named: "custom_pin.png")
marker.map = mapView
// Generate many markers
let markerArray = MarkerGenerator(near: mapCenter, count: 100).markerArray
// Comment the following code out if using the marker clusterer
// to manage markers instead.
// for marker in markerArray {
// marker.map = mapView
// }
// Set up the cluster manager with a supplied icon generator and renderer.
let algorithm = GMUNonHierarchicalDistanceBasedAlgorithm()
let iconGenerator = GMUDefaultClusterIconGenerator()
let renderer = GMUDefaultClusterRenderer(mapView: mapView, clusterIconGenerator: iconGenerator)
clusterManager = GMUClusterManager(map: mapView, algorithm: algorithm, renderer: renderer)
clusterManager.setMapDelegate(self)
clusterManager.add(markerArray)
clusterManager.cluster()
}
8. אינטראקציה של משתמש
עכשיו יש לך מפה נראית מצוינת שמציגה סמנים ומשתמשת באשכולות סמנים. בשלב זה, עליך להוסיף עוד טיפול על אינטראקציות המשתמשים באמצעות GMSMapViewDelegate
, שהגדרת קודם לבקר המידע על התצוגה, כדי לשפר את חוויית המשתמש במפה.
ה-SDK של מפות ל-iOS מספק מערכת אירועים מקיפה שמיושמת באמצעות הענקת גישה לתצוגת מפה, הכוללת רכיבי handler של אירועים שמאפשרים להפעיל קוד כשמתרחשות אינטראקציות שונות של משתמשים. לדוגמה, ההאצלה של תצוגת ה-ViewView כוללת שיטות המופעלות להפעלת קוד על סמך אינטראקציות, כמו המשתמש לוחץ על המפה והסמנים, להזיז את תצוגת המפה, להתקרב ולהתרחק מהתצוגה ועוד.
בשלב זה, עליך להזיז את המפה באופן פרוגרמטי כדי למרכז את הסמן שעליו המשתמש מקיש.
- הטמעה של מכשיר ההאזנה בהקשה.
התכונה mapView(_:didTap:)
נקראת בכל פעם שהמשתמש מקיש על אחד מהסמנים שיצרתם קודם לכן, ובכל פעם שמשתמש מקיש על אשכול סמן (באופן פנימי, אשכולות הסמן מוטמעים כמופע של GMSMarker
).
כדי להטמיע את ה- event listener, תחילה צריך להדביק אותו בחלק התחתון של ViewController.swift
לפני סוגר הסוגריים המסולסל.
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
return false
}
חשוב לשים לב שהשיטה מחזירה false
. פעולה זו מורה ל-iOS SDK להמשיך לבצע את פונקציונליות ברירת המחדל של GMSMarker
, כמו הצגת חלון מידע, אם מוגדר, לאחר ביצוע קוד ה-handler של האירוע.
- יש לטפל באירוע ההקשה ולהגדיר אנימציה של המצלמה כדי למרכז את המפה כאשר מקישים על סמן או על אשכול סמנים.
כשמתקשרים, mapView(_:didTap:)
מעביר את המופע של GMSMarker
שנלחץ כדי שניתן יהיה לטפל בו בקוד. ניתן להשתמש במופע הזה כדי למרכז את המפה על ידי קריאה ל-animate(toLocation:)
בתצוגת המפה מתוך ה-handler של האירוע ולהעביר אותה למיקום של מופע הסמן מתוך הנכס position
.
// Animate to the marker
mapView.animate(toLocation: marker.position)
- הגדלת התצוגה של אשכול הסמן בעת הקשה.
דפוס טיפוסי של חוויית משתמש הוא הגדלת האשכולות של הסמן בעת ההקשה. כך המשתמשים יכולים להציג את הסימונים המקובצים באשכולות, ככל שהאשכול מתרחב ברמות נמוכות יותר.
כפי שצוין קודם, סמל אשכול הסמן הוא למעשה הטמעה של GMSMarker
עם סמל מותאם אישית. אז איך אפשר לדעת אם בוצעה הקשה על סמן או על אשכול סימנים? כאשר מנהל האשכולות של הסמן יוצר סמל אשכול חדש, הוא מטמיע את המופע של GMSMarker
כדי להתאים לפרוטוקול בשם GMUCluster.
תוכל להשתמש בתנאי כדי לבדוק אם הסמן המועבר אל ה-handler של האירועים תואם לפרוטוקול הזה.
אחרי שידוע באופן פרוגרמטי שמקישים על אשכול, אפשר להתקשר ל-animate(toZoom:)
במופע של תצוגת המפה ולהגדיר את מרחק התצוגה עד לרמת הזום הנוכחית. רמת מרחק התצוגה הנוכחית זמינה במופע של mapView בנכס camera.zoom
.
כמו כן, חשוב לשים לב איך הקוד הבא מחזיר את true
. פעולה זו נותנת ל-handler של האירוע שהשלמתם את הטיפול באירוע ולא להפעיל קוד נוסף ב-handler. אחת מהסיבות לכך היא למנוע מאובייקט GMSMarker
לבצע את שאר התנהגות ברירת המחדל שלו, כמו הצגת חלון מידע שלא יהיה הגיוני במקרה של הקשה על סמל של אשכול.
// If the tap was on a marker cluster, zoom in on the cluster
if let _ = marker.userData as? GMUCluster {
mapView.animate(toZoom: mapView.camera.zoom + 1)
return true
}
עכשיו טוענים מחדש את האפליקציה ומקישים על כמה סמנים ואשכולות סמנים. לאחר ההקשה, המפה תופיע מחדש באלמנט שעליו הקשת. כאשר מקישים על אשכול סמן, המפה תגדל גם ברמה אחת, ואשכול הסמן יתרחב כדי להציג את הסימונים המקובצים במקבצים.
לסיכום, בשלב זה הטמעתם את הכלי להאזנה בהקשה
שיטת mapView(_:didTap:)
צריכה להיראות כך:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
// Animate to the marker
mapView.animate(toLocation: marker.position)
// If the tap was on a marker cluster, zoom in on the cluster
if let _ = marker.userData as? GMUCluster {
mapView.animate(toZoom: mapView.camera.zoom + 1)
return true
}
return false
}
9. ציור על המפה
עד עכשיו, יצרת מפה של סידני שמראה סמנים ב-100 נקודות אקראיות ומטפלת באינטראקציה של משתמשים. בשלב האחרון של שיעור הקוד, אתם משתמשים בתכונות השרטוט של ה-SDK של מפות Google ל-iOS כדי להוסיף עוד פיצ'רים שימושיים לחוויית המפה.
נניח שהמפה הזו תשמש את המשתמשים שרוצים לחקור את העיר סידני. תכונה שימושית היא תצוגה חזותית של רדיוס מסביב לסמן בזמן לחיצה עליו. כך המשתמש יוכל להבין בקלות אילו יעדים אחרים נמצאים במרחק הליכה קל מהסמן שעליו הוא לוחץ.
ה-SDK של iOS כולל קבוצה של פונקציות לציור צורות במפה, כמו ריבועים, פוליגונים, קווים ומעגלים. בשלב זה, מעבדים עיגול כדי להציג רדיוס של 800 מטר מסביב לסמן בעת לחיצה עליו.
- יש להוסיף משתנה מופע
circle
אל ה-ViewController.
משתנה זה של מופע משמש לשמירה של המעגל האחרון שנשלף, כדי שניתן יהיה להשמיד אותו עוד לפני שמציירים אותו. בסופו של דבר, זה לא יועיל למשתמש והוא לא ייראה טוב אם כל סמן שעליו הקשת יכסה עיגול!
לשם כך, יש לעדכן את ההטמעה של ViewController
באופן הבא:
class ViewController: UIViewController, GMSMapViewDelegate {
private var mapView: GMSMapView!
private var clusterManager: GMUClusterManager!
private var circle: GMSCircle? = nil
...
}
- משרטטים את העיגול כשמקישים על סמן.
בתחתית השיטה mapView(_:didTap:)
שנמצאת מעל להצהרה ב-return false
, מוסיפים את הקוד שמוצג כאן כדי ליצור מופע של כיתה GMSCircle
מה-SDK של iOS. כדי לשרטט מעגל רדיוס חדש של 800 מטר, יש להעביר אותו אל GMSCircle(position:radius:)
ולעבור אותו למיקום של הסמן שהקשת עליו כפי שפעלת כשהמרת את המפה.
// Draw a new circle around the tapped marker
circle = GMSCircle(position: marker.position, radius: 800)
- מעצבים את המעגל.
כברירת מחדל, GMSCircle
משרטטת מעגל עם קו חוצה מלא ומילוי שקוף. זה פועל לצורך הצגת הרדיוס, אבל הוא לא נראה טוב במיוחד וקצת קשה לראות אותו. לאחר מכן, אפשר לשנות את הסגנון של המעגל כדי לשפר את העיצוב על ידי הקצאת UIColor
למאפיין fillColor
של העיגול. הקוד שמוצג כאן מוסיף מילוי אפור ב-50% שקיפות:
circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
- עיבוד העיגול במפה.
בדיוק כמו שיצרתם סמנים לפני כן, יצירת מופע של GMSCircle
לא גורמת לו להופיע במפה. לשם כך, יש להקצות את המופע של תצוגת המפה לנכס map
בעיגול.
circle?.map = mapView
- יש להסיר מעגלים שעובדו בעבר.
כפי שצוין קודם לכן, לא תהיה חוויית משתמש טובה מאוד להמשיך להוסיף מעגלים למפה. כדי להסיר את העיגול שנוצר על ידי אירוע הקשה קודם, יש להגדיר את המאפיין map
של circle
ל-nil
בחלק העליון של mapView(_:didTap:)
.
// Clear previous circles
circle?.map = nil
טוענים מחדש את האפליקציה ומקישים על סמן. אמור להופיע מעגל חדש שמודגש בכל פעם שמקישים על סמן, וכל עיגול שעבר עיבוד בעבר הוסר כפי שמוצג באיור 7.
איור 7. עיגול שמקיף את הסמן שעליו מקישים.
לסיכום, בשלב הזה השתמשת בכיתה GMSCircle
כדי לעבד עיגול בכל פעם שמקישים על סמן.
שיטת mapView(_:didTap:)
צריכה להיראות כך:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
// Clear previous circles
circle?.map = nil
// Animate to the marker
mapView.animate(toLocation: marker.position)
// If the tap was on a marker cluster, zoom in on the cluster
if let _ = marker.userData as? GMUCluster {
mapView.animate(toZoom: mapView.camera.zoom + 1)
return true
}
// Draw a new circle around the tapped marker
circle = GMSCircle(position: marker.position, radius: 800)
circle?.fillColor = UIColor(red: 0.67, green: 0.67, blue: 0.67, alpha: 0.5)
circle?.map = mapView
return false
}
10. מזל טוב
יצרת בהצלחה אפליקציה ל-iOS שמציגה מפת Google אינטראקטיבית.
מה למדת
- טעינה והגדרה של ה-SDK של מפות Google ל-iOS ול-SDK של מפות Google ל-iOS ספריית כלי עזר
- המערכת טוענת מפה
- סגנון עיצוב מפה
- שימוש בסמנים, סמנים בהתאמה אישית ואשכולות סמנים
- מערכת האירועים כדי לספק אינטראקציה למשתמש
- שליטה במצלמת המפה באופן פרוגרמטי
- שרטוט במפה
מה עכשיו?
- מומלץ לעיין במאגר
maps-sdk-for-ios-samples
של GitHub לדוגמה או בהדגמות כדי לקבל השראה ולקבל השראה - למידה מתכונות קוד נוספות של Swift על בניית אפליקציות ל-iOS באמצעות הפלטפורמה של מפות Google
- ענו על השאלה הבאה כדי לעזור לנו ליצור את התוכן השימושי ביותר:
אילו מעבדי קוד אחרים היית רוצה לראות?
האם קוד הקוד שאתם לא רוצים מופיע למעלה? אפשר לבקש אותו באמצעות בעיה חדשה כאן.