סמנים מציינים מיקומים בודדים במפה.
כברירת מחדל, הסמנים משתמשים בסמל סטנדרטי עם המראה והתחושה המוכרים של מפות Google. אם רוצים להתאים אישית את הסמן, אפשר לשנות את הצבע של הסמן שמוגדר כברירת מחדל, להחליף את תמונת הסמן בסמל מותאם אישית או לשנות מאפיינים אחרים של הסמן.
בתגובה לאירוע לחיצה על סמן, אפשר לפתוח חלון מידע. חלון מידע מציג טקסט או תמונות בחלון דו-שיח מעל הסמן. אפשר להשתמש בחלון מידע שמוגדר כברירת מחדל כדי להציג טקסט, או ליצור חלון מידע בהתאמה אישית כדי לשלוט לחלוטין בתוכן שלו.
הוספת סמן
כדי להוסיף סמן, יוצרים אובייקט GMSMarker
שכולל position
ו-title
, ומגדירים את map
שלו.
בדוגמה הבאה מוסבר איך מוסיפים סמן לאובייקט GMSMapView
קיים. הסמן נוצר בקואורדינטות 10,10
, וכשלוחצים עליו מוצג המחרוזת Hello world בחלון מידע.
Swift
let position = CLLocationCoordinate2D(latitude: 10, longitude: 10) let marker = GMSMarker(position: position) marker.title = "Hello World" marker.map = mapView
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(10, 10); GMSMarker *marker = [GMSMarker markerWithPosition:position]; marker.title = @"Hello World"; marker.map = mapView;
אפשר להנפיש את ההוספה של סמנים חדשים למפה על ידי הגדרת המאפיין marker.appearAnimation
לערך:
-
kGMSMarkerAnimationPop
כדי שהסמן יקפוץ מה-groundAnchor
כשהוא יתווסף. -
kGMSMarkerAnimationFadeIn
כדי שהסימן יופיע בהדרגה כשהוא מתווסף.
הסרת סמן
כדי להסיר סמן מהמפה, צריך להגדיר את המאפיין map
של GMSMarker
ל-nil
. אפשר גם להסיר את כל שכבות העל (כולל סמנים) שמוצגות כרגע במפה באמצעות קריאה לשיטה GMSMapView
clear
.
Swift
let camera = GMSCameraPosition.camera( withLatitude: -33.8683, longitude: 151.2086, zoom: 6 ) let mapView = GMSMapView.map(withFrame: .zero, camera: camera) // ... mapView.clear()
Objective-C
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683 longitude:151.2086 zoom:6]; mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera]; // ... [mapView clear];
אם רוצים לבצע שינויים בסמן אחרי שמוסיפים אותו למפה, צריך לוודא ששומרים את האובייקט GMSMarker
. אפשר לשנות את הסמן מאוחר יותר על ידי שינוי האובייקט הזה.
Swift
let position = CLLocationCoordinate2D(latitude: 10, longitude: 10) let marker = GMSMarker(position: position) marker.map = mapView // ... marker.map = nil
Objective-C
CLLocationCoordinate2D position = CLLocationCoordinate2DMake(10, 10); GMSMarker *marker = [GMSMarker markerWithPosition:position]; marker.map = mapView; // ... marker.map = nil;
שינוי צבע הסמן
אתם יכולים להתאים אישית את הצבע של תמונת הסמן שמוגדרת כברירת מחדל על ידי שליחת בקשה לגרסה מוצללת של סמל ברירת המחדל עם markerImageWithColor:
, והעברת התמונה שמתקבלת למאפיין הסמל של GMSMarker
.
Swift
marker.icon = GMSMarker.markerImage(with: .black)
Objective-C
marker.icon = [GMSMarker markerImageWithColor:[UIColor blackColor]];
התאמה אישית של תמונת הסמן
אם רוצים לשנות את תמונת ברירת המחדל של הסמן, אפשר להגדיר סמל מותאם אישית באמצעות המאפיין icon
או iconView
של הסמן. אם המאפיין iconView
מוגדר, ה-API מתעלם מהמאפיין icon
.
שימוש במאפיין icon
של הסמן
בקטע הקוד הבא נוצר סמן עם סמל מותאם אישית שמוגדר כ-UIImage
במאפיין icon
. הסמל ממוקם במרכז בלונדון, אנגליה. הקטע
מניח שהאפליקציה מכילה תמונה בשם house.png.
Swift
let positionLondon = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127) let london = GMSMarker(position: positionLondon) london.title = "London" london.icon = UIImage(named: "house") london.map = mapView
Objective-C
CLLocationCoordinate2D positionLondon = CLLocationCoordinate2DMake(51.5, -0.127); GMSMarker *london = [GMSMarker markerWithPosition:positionLondon]; london.title = @"London"; london.icon = [UIImage imageNamed:@"house"]; london.map = mapView;
אם יוצרים כמה סמנים עם אותה תמונה, צריך להשתמש באותו מופע של UIImage
לכל אחד מהסמנים. כך אפשר לשפר את הביצועים של האפליקציה כשמוצגים בה הרבה סמנים.
יכול להיות שיש לתמונה הזו כמה פריימים. בנוסף, המערכת מתחשבת במאפיין alignmentRectInsets
, ששימושי אם לסמן יש צל או אזור אחר שלא ניתן להשתמש בו.
שימוש במאפיין iconView
של הסמן
קטע הקוד הבא יוצר סמן עם סמל מותאם אישית על ידי הגדרת המאפיין iconView
של הסמן, ומציג אנימציה של שינוי בצבע הסמן.
קטע הקוד מניח שהאפליקציה מכילה תמונה בשם house.png.
Swift
import CoreLocation import GoogleMaps class MarkerViewController: UIViewController, GMSMapViewDelegate { var mapView: GMSMapView! var london: GMSMarker? var londonView: UIImageView? override func viewDidLoad() { super.viewDidLoad() let camera = GMSCameraPosition.camera( withLatitude: 51.5, longitude: -0.127, zoom: 14 ) let mapView = GMSMapView.map(withFrame: .zero, camera: camera) view = mapView mapView.delegate = self let house = UIImage(named: "House")!.withRenderingMode(.alwaysTemplate) let markerView = UIImageView(image: house) markerView.tintColor = .red londonView = markerView let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127) let marker = GMSMarker(position: position) marker.title = "London" marker.iconView = markerView marker.tracksViewChanges = true marker.map = mapView london = marker } func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) { UIView.animate(withDuration: 5.0, animations: { () -> Void in self.londonView?.tintColor = .blue }, completion: {(finished) in // Stop tracking view changes to allow CPU to idle. self.london?.tracksViewChanges = false }) } }
Objective-C
@import CoreLocation; @import GoogleMaps; @interface MarkerViewController : UIViewController <GMSMapViewDelegate> @property (strong, nonatomic) GMSMapView *mapView; @end @implementation MarkerViewController { GMSMarker *_london; UIImageView *_londonView; } - (void)viewDidLoad { [super viewDidLoad]; GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:51.5 longitude:-0.127 zoom:14]; _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera]; self.view = _mapView; _mapView.delegate = self; UIImage *house = [UIImage imageNamed:@"House"]; house = [house imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; _londonView = [[UIImageView alloc] initWithImage:house]; _londonView.tintColor = [UIColor redColor]; CLLocationCoordinate2D position = CLLocationCoordinate2DMake(51.5, -0.127); _london = [GMSMarker markerWithPosition:position]; _london.title = @"London"; _london.iconView = _londonView; _london.tracksViewChanges = YES; _london.map = self.mapView; } - (void)mapView:(GMSMapView *)mapView idleAtCameraPosition:(GMSCameraPosition *)position { [UIView animateWithDuration:5.0 animations:^{ self->_londonView.tintColor = [UIColor blueColor]; } completion:^(BOOL finished) { // Stop tracking view changes to allow CPU to idle. self->_london.tracksViewChanges = NO; }]; } @end
מכיוון שהתג iconView
מקבל UIView
, אפשר ליצור היררכיה של רכיבי בקרה רגילים בממשק המשתמש שמגדירים את הסמנים, כאשר לכל תצוגה יש את קבוצת היכולות הרגילה של אנימציה. אפשר לכלול שינויים בגודל, בצבע וברמות האלפא של הסמן, וגם להחיל טרנספורמציות שרירותיות. המאפיין iconView
תומך באנימציה של כל המאפיינים שניתן להוסיף להם אנימציה של UIView
, מלבד frame
ו-center
.
חשוב לשים לב לשיקולים הבאים כשמשתמשים ב-iconView
:
- השימוש ב-
UIView
עלול להיות אינטנסיבי מבחינת משאבים כש-tracksViewChanges
מוגדר ל-YES
, ולכן עלול להגביר את השימוש בסוללה. לעומת זאת, פריים בודדUIImage
הוא סטטי ולא צריך לעבד אותו מחדש. - יכול להיות שחלק מהמכשירים יתקשו לעבד את המפה אם יש הרבה סמנים במסך, ולכל סמן יש
UIView
משלו, וכל הסמנים עוקבים אחרי שינויים בו-זמנית. iconView
לא מגיב לאינטראקציה של המשתמש, כי הוא תמונה של התצוגה.- התצוגה מתנהגת כאילו הערך של
clipsToBounds
הואYES
, בלי קשר לערך בפועל. אפשר להחיל טרנספורמציות שפועלות מחוץ לגבולות, אבל האובייקט שמציירים צריך להיות בתוך הגבולות של האובייקט. כל השינויים/ההמרות נמצאים במעקב ומיושמים. בקיצור: תצוגות משנה צריכות להיות בתוך התצוגה. - כדי להשתמש ב-
-copyWithZone:
ב-GMSMarker
, צריך קודם להעתיק אתGMSMarker
ואז להגדיר מופע חדש שלiconView
בעותק.UIView
לא תומך ב-NSCopying
, ולכן אי אפשר להעתיק אתiconView
.
כדי להחליט מתי להגדיר את המאפיין tracksViewChanges
, צריך לשקול את ההשפעה על הביצועים לעומת היתרונות של סימון מחדש באופן אוטומטי. לדוגמה:
- אם רוצים לבצע כמה שינויים, אפשר לשנות את הנכס ל
YES
ואז להחזיר אותו לNO
. - אם מפעילים אנימציה או אם התוכן נטען באופן אסינכרוני, צריך להשאיר את המאפיין מוגדר לערך
YES
עד שהפעולות יסתיימו.
שינוי השקיפות של הסמן
אפשר לשלוט באטימות של סמן באמצעות המאפיין opacity
שלו. צריך לציין את האטימות כמספר עשרוני בין 0.0 ל-1.0, כאשר 0 הוא שקוף לחלוטין ו-1 הוא אטום לחלוטין.
Swift
marker.opacity = 0.6
Objective-C
marker.opacity = 0.6;
אפשר להנפיש את אטימות הסמן באמצעות Core Animation באמצעות GMSMarkerLayer
.
השטחת סמן
סמלי הסמנים מוצגים בדרך כלל בהתאם למסך המכשיר ולא בהתאם לפני השטח של המפה, כך שסיבוב, הטיה או שינוי מרחק התצוגה של המפה לא משנים בהכרח את הכיוון של הסמן.
אפשר להגדיר את הכיוון של סמן כך שיהיה שטוח ביחס לכדור הארץ. סמנים שטוחים מסתובבים כשמסובבים את המפה, ומשנים את נקודת המבט כשמטים את המפה. בדומה לסמנים רגילים, סמנים שטוחים שומרים על הגודל שלהם כשמבצעים זום אין או זום אאוט במפה.
כדי לשנות את הכיוון של הסמן, מגדירים את המאפיין flat
של הסמן לערך
YES
או true
.
Swift
let positionLondon = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127) let londonMarker = GMSMarker(position: positionLondon) londonMarker.isFlat = true londonMarker.map = mapView
Objective-C
CLLocationCoordinate2D positionLondon = CLLocationCoordinate2DMake(51.5, -0.127); GMSMarker *londonMarker = [GMSMarker markerWithPosition:positionLondon]; londonMarker.flat = YES; londonMarker.map = mapView;
סיבוב של סמן
כדי לסובב סמן סביב נקודת העוגן שלו, מגדירים את המאפיין rotation
. מציינים את הסיבוב כסוג CLLocationDegrees
, שנמדד במעלות בכיוון השעון מהמיקום שמוגדר כברירת מחדל. כשהסמן שטוח על המפה,
המיקום שמוגדר כברירת מחדל הוא צפון.
בדוגמה הבאה, הסמן מסובב ב-90 מעלות. הגדרת המאפיין groundAnchor
לערך 0.5,0.5
גורמת לסיבוב הסמן סביב המרכז שלו, במקום סביב הבסיס שלו.
Swift
let degrees = 90.0 londonMarker.groundAnchor = CGPoint(x: 0.5, y: 0.5) londonMarker.rotation = degrees londonMarker.map = mapView
Objective-C
CLLocationDegrees degrees = 90; londonMarker.groundAnchor = CGPointMake(0.5, 0.5); londonMarker.rotation = degrees; londonMarker.map = mapView;
טיפול באירועים בסמנים
אפשר להאזין לאירועים שמתרחשים במפה, למשל כשמשתמש מקיש על סמן. כדי להאזין לאירועים, צריך להטמיע את הפרוטוקול GMSMapViewDelegate
. במאמר אירועי סמן ומחוות מוסבר איך לטפל באירועי סמן ספציפיים. במדריך לאירועים מופיעה גם רשימה של שיטות ב-GMSMapViewDelegate. במאמר GMSPanoramaViewDelegate
מוסבר על אירועי Street View.