סמנים

בחירת פלטפורמה: 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. אפשר גם להסיר את כל שכבות-העל (כולל סמנים) שמוצגות כרגע במפה באמצעות קריאה ל-method‏ GMSMapView clear.

Swift

let camera = GMSCameraPosition.camera(
  withLatitude: -33.8683,
  longitude: 151.2086,
  zoom: 6
)
let options = GMSMapViewOptions()
options.camera = camera
let mapView = GMSMapView(options: options)
// ...
mapView.clear()
      

Objective-C

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683
                                                        longitude:151.2086
                                                             zoom:6];
GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init];
options.camera = camera;
mapView = [[GMSMapView alloc] initWithOptions:options];
// ...
[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 options = GMSMapViewOptions()
    options.camera = camera
    let mapView = GMSMapView(options: options)
    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];
  GMSMapViewOptions *options = [[GMSMapViewOptions alloc] init];
  options.camera = camera;
  _mapView = [[GMSMapView alloc] initWithOptions:options];
  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. לאירועים של Street View, ראו GMSPanoramaViewDelegate.