סמנים

בחירת פלטפורמה: Android iOS JavaScript

סמנים מציינים מיקומים בודדים במפה.

כברירת מחדל, הסמנים משתמשים בסמל סטנדרטי עם המראה והתחושה המוכרים של מפות 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.