סמנים מציינים מיקומים בודדים במפה.
כברירת מחדל, הסמנים מוצגים עם סמל סטנדרטי שתואם למראה ולתחושה של מפות 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
. לחלופין, אפשר להסיר את כל שכבות-העל (כולל הסמנים) שמוצגות כרגע במפה על-ידי קריאה ל-method 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
:
- כשהערך של
tracksViewChanges
מוגדר כ-YES
, ה-UIView
יכול לדרוש הרבה משאבים, וכתוצאה מכך יכול להיות שימוש מוגבר בסוללה. לעומת זאת, פריים יחידUIImage
הוא סטטי ואין צורך לבצע עיבוד חוזר שלו. - יכול להיות שבמכשירים מסוימים תהיה בעיה ברינדור המפה אם יש הרבה סמנים במסך, לכל אחד מהסמנים יש
UIView
משלו וכל הסמנים עוקבים אחרי שינויים בו-זמנית. iconView
לא מגיב לאינטראקציה של משתמשים, כי הוא צילום של התצוגה.- התצוגה מתנהגת כאילו
clipsToBounds
מוגדר ל-YES
, ללא קשר לערך בפועל שלו. אפשר להחיל טרנספורמציות שעובדות מחוץ לגבולות, אבל האובייקט שתרצו לצייר צריך להיות בתוך גבולות האובייקט. כל הטרנספורמציות או השינויים נמצאים במעקב והם מיושמים. בקיצור: תצוגות משנה חייבות להיות כלולות בתצוגה.
כדי להחליט מתי להגדיר את המאפיין tracksViewChanges
, צריך לשקול את השיקולים לגבי הביצועים מול היתרונות של ציור מחדש אוטומטי של הסמן. לדוגמה:
- אם אתם צריכים לבצע סדרה של שינויים, תוכלו לשנות את המאפיין לערך
YES
ואז חזרה לערךNO
. - כשאנימציה פועלת או שהתכנים נטענים באופן אסינכרוני, צריך להשאיר את הערך של המאפיין כ-
YES
עד שהפעולות יושלמו.
שינוי שקיפות הסמן
אפשר לשלוט בשקיפות של סמן באמצעות המאפיין opacity
שלו. צריך לציין את העכירות כערך של משתנה מסוג float בין 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. מידע על אירועי Street View זמין במאמר GMSPanoramaViewDelegate
.