【问题标题】:Google Maps iOS SDK move "My Location" button to bottom left hand cornerGoogle Maps iOS SDK 将“我的位置”按钮移至左下角
【发布时间】:2013-05-28 14:20:47
【问题描述】:

使用 Google Maps for iOS SDK,“我的位置”按钮默认位于右下角:

我想把它放在左下角(是的,我意识到我需要小心不要遮挡那里的“Google”徽标)。我不相信 SDK 有这样做的“官方”方式,但基于this answer,我已经想出了如何获取“我的位置”按钮子视图以便我可以定位它。

让我感到困惑的部分是我应该为“我的位置”视图的框架和/或边界赋予什么值,才能将它放在我想要的位置。对于初学者来说,当前的“我的位置”按钮有 frame.origin.x = -74frame.origin.y = -54。这是我第一次看到 frame.origin.xframe.origin.y 的负坐标,我什至不确定 iOS 如何处理负坐标。我的第一个想法是,例如frame.origin.x = -74 等价于[view superview].frame.size.width - 74,即从父视图的宽度或高度中减去负值。但后来我查看了超级视图的宽度和高度,它们都是0.0。这是我的代码,它输出有关地图和我的位置按钮框架和边界的一些信息:

- (void)loadView {
    GMSCameraPosition *cam = [GMSCameraPosition cameraWithLatitude:jcuTownsvilleCenterCampusLat longitude:jcuTownsvilleCenterCampusLon zoom:17];
    self.campusMap = [GMSMapView mapWithFrame:CGRectZero camera:cam];
    self.campusMap.myLocationEnabled = YES;
    self.campusMap.settings.myLocationButton = YES;
    self.view = self.campusMap;

    for (UIView *view in self.campusMap.subviews) {
        NSLog(@"view.description: %@",view.description);
        if ([view isKindOfClass:[UIButton class]]) {
            // these four values in the conditional below are just what happen to
            // be the values corresponding to the "my location button" in Google Maps
            // for iOS SDK version 1.3.0.3430.  They might change over time, so this
            // code is somewhat fragile.
            if (view.frame.size.width == 76 && view.frame.size.height == 54 &&
                view.frame.origin.x == -76 && view.frame.origin.y == -54) {
                NSLog(@"we may have found the 'my location' button");

                NSLog(@"self.campusMap coord stats:");
                NSLog(@"bounds.origin.x: %f", self.campusMap.bounds.origin.x);
                NSLog(@"bounds.origin.y: %f", self.campusMap.bounds.origin.y);
                NSLog(@"bounds.size.width: %f", self.campusMap.bounds.size.width);
                NSLog(@"bounds.size.height: %f", self.campusMap.bounds.size.height);
                NSLog(@"frame.origin.x: %f", self.campusMap.frame.origin.x);
                NSLog(@"frame.origin.y: %f", self.campusMap.frame.origin.y);
                NSLog(@"frame.size.width: %f", self.campusMap.frame.size.width);
                NSLog(@"frame.size.height: %f", self.campusMap.frame.size.height);

                NSLog(@"view coord stats:");
                NSLog(@"bounds.origin.x: %f", view.bounds.origin.x);
                NSLog(@"bounds.origin.y: %f", view.bounds.origin.y);
                NSLog(@"bounds.size.width: %f", view.bounds.size.width);
                NSLog(@"bounds.size.height: %f", view.bounds.size.height);
                NSLog(@"frame.origin.x: %f", view.frame.origin.x);
                NSLog(@"frame.origin.y: %f", view.frame.origin.y);
                NSLog(@"frame.size.width: %f", view.frame.size.width);
                NSLog(@"frame.size.height: %f", view.frame.size.height);
            }
        }
    }
}  

这是输出:

self.campusMap coord stats:    
bounds.origin.x: 0.000000  
bounds.origin.y: 0.000000  
bounds.size.width: 0.000000  
bounds.size.height: 0.000000  
frame.origin.x: 0.000000  
frame.origin.y: 0.000000  
frame.size.width: 0.000000  
frame.size.height: 0.000000  
view coord stats:  
bounds.origin.x: 0.000000  
bounds.origin.y: 0.000000  
bounds.size.width: 76.000000  
bounds.size.height: 54.000000  
frame.origin.x: -76.000000  
frame.origin.y: -54.000000  
frame.size.width: 76.000000  
frame.size.height: 54.000000

我尝试将“我的位置”按钮放置在顶部左上角作为一个简单的测试:

CGRect frame = view.frame;
frame.origin.x = 0;
frame.origin.y = 0;
frame.size.width = 76;
frame.size.height = 54;
[view setFrame:frame];

但是我的位置按钮根本没有显示。

我还尝试对现有值进行小幅修改(例如,将 frame.origin.x-76.0 更改为 -66.0 并且可以看到位置的差异,所以至少我确信我正在修改正确的视图。我仍然不明白 i)负坐标是如何工作的,以及 ii)如何在这个特定场景中正确定位视图。在阅读了this question 的答案后,我认为我对视图框架和边界有一个合理的掌握,但鉴于我还没有让它工作,显然没有。

【问题讨论】:

  • loadView 中,您刚刚分配了大小为零的地图视图(这会导致它被调整大小以填充屏幕)。在稍后的某个时间点检查所有值可能是值得的 - 例如在 viewDidLoadviewDidAppear 或类似的东西?
  • 检查按钮的transform 属性的值可能也是值得的,以查看转换是否设置为异常值。

标签: ios objective-c google-maps-sdk-ios


【解决方案1】:
for (UIView *object in _mapView.subviews) {
    if([[[object class] description] isEqualToString:@"GMSUISettingsPaddingView"] )
    {
        for (UIView *settingView in object.subviews) {
            if([[[settingView class] description] isEqualToString:@"GMSUISettingsView"] )
            {
                for(UIView *view in settingView.subviews) {
                    if([[[view class] description] isEqualToString:@"GMSx_QTMButton"] ) {
                        CGRect frame = view.frame;
                        frame.origin.y -= 60;
                        view.frame = frame;
                    }
                }
            }
        };

    }
}

【讨论】:

    【解决方案2】:

    您可以使用 GMSMapView 的填充。

    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-37.81969
                                                            longitude:144.966085
                                                                 zoom:4];
    _mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];
    
    _mapView.settings.myLocationButton = YES;
    _mapView.myLocationEnabled = YES;
    _mapView.padding = UIEdgeInsetsMake(0, 0, kOverlayHeight, 0);
    self.view = _mapView;
    

    SWIFT 3

    self._mapView.padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    

    【讨论】:

    • 斯威夫特 3:viewMap.padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    【解决方案3】:

    在 swift 3 xcode 8 中

    func moveLocationButton() -> Void{
         for object in mapView.subviews{
            for obj in object.subviews{
               if let button = obj as? UIButton{
                 let name = button.accessibilityIdentifier
                    if(name == "my_location"){
                            //config a position
                            button.center = self.view.center 
                        }
                    }
                }
            }
        }
    

    【讨论】:

      【解决方案4】:

      截至 2015 年 7 月,这是一种实现方式:

      for (UIView *object in mapView_.subviews) {
          if([[[object class] description] isEqualToString:@"GMSUISettingsView"] )
          {
              for(UIView *view in object.subviews) {
                  if([[[view class] description] isEqualToString:@"GMSx_QTMButton"] ) {
                      CGRect frame = view.frame;
                      frame.origin.y -= 60;
                      view.frame = frame;
                  }
              }
      
          }
      };
      

      【讨论】:

        【解决方案5】:
        for (UIView *object in mapView_.subviews) {
            if([[[object class] description] isEqualToString:@"GMSUISettingsView"] )
            {
                for(UIView *view in object.subviews) {
                    if([[[view class] description] isEqualToString:@"UIButton"] ) {
                        CGRect frame = view.frame;
                        frame.origin.y -= 60;
                        view.frame = frame;
                    }
                }
        
            }
        };
        

        【讨论】:

          【解决方案6】:

          解决此问题的最简单方法是在创建地图视图后立即更改按钮的框架和自动调整大小掩码。

          UIButton* myLocationButton = (UIButton*)[[mapView_ subviews] lastObject];
          myLocationButton.autoresizingMask = UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleTopMargin;
          CGRect frame = myLocationButton.frame;
          frame.origin.x = 5;
          myLocationButton.frame = frame;
          

          编辑:抱歉,我把按钮放在了右上角。更新了我的代码,将其放在左下角。

          注意:目前没有来自 Google 的 API 来获取位置按钮。第一行可能在 SDK 的未来版本中不起作用。

          您还应该创建一个功能请求here

          另一种选择是自己创建按钮并将其作为子视图添加到地图中。 按钮处理程序代码相当简单:

            CLLocation *location = mapView_.myLocation;
            if (location) {
              [mapView_ animateToLocation:location.coordinate];
            }
          

          【讨论】:

          • 我将其标记为已接受,因为它或多或少地完成了所要求的操作。我还没有想出如何摆脱按钮周围的“填充”(例如尝试frame.origin.x = 0,它仍然离角落有点远)。在 UIButton 上将 contentEdgeInsetstitleEdgeInsetsimageEdgeInsets 设置为 0.0 似乎也不太好。
          • 更新:在 Google Maps iOS SDK 版本 1.4.0.4450 中,myLocation 按钮已更改其在视图层次结构中的位置,因此无法再通过上述[[mapView_ subviews] lastObject] 访问。我现在用...
          • for (UIView *view in self.mapView.subviews) { NSString *viewClassString = NSStringFromClass([view class]); if ([viewClassString rangeOfString:@"GMSUISettingsView"].location != NSNotFound) { for (UIView *view2 in view.subviews) { if ([view2 isKindOfClass:[UIButton class]]) { _myLocationButton = (UIButton *)view2; } } } }
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-01-07
          • 1970-01-01
          • 2013-05-17
          • 2016-05-21
          相关资源
          最近更新 更多