如何在iOS的Google地图上添加一个按钮?

13

我是iOS编程的新手,已经下载了适用于iOS的谷歌地图SDK,并按照他们网站上的说明进行操作(如链接所示:https://developers.google.com/maps/documentation/ios/start),成功在我的应用程序中添加了地图。

现在我想在Google地图上方加一个按钮,为用户提供返回上一页的选项。

我知道UIButton是UIView的子类,通过将它作为该类的子视图之一,我们可以使按钮出现在视图上。之前iOS默认使用MKMapView来使用Google Maps,并且我在书籍和网络上看到过一些示例,其中按钮或文本框会出现在地图上。但是现在,在界面构建器中拖动按钮并不能帮助解决Google Maps的SDK问题。

这是我的代码:

ViewController.h

#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
#import <GoogleMaps/GoogleMaps.h>


@interface ViewController : UIViewController 

@property (weak, nonatomic) IBOutlet UIButton *btn;


@end

ViewController.m

#import "ViewController.h"
#import <MapKit/MapKit.h>
#import <GoogleMaps/GoogleMaps.h>
#import <CoreLocation/CoreLocation.h>


@interface ViewController ()

@end

@implementation ViewController
{
    GMSMapView *mapView_;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)loadView
{
    CLLocationManager *locationManager = [[CLLocationManager alloc] init];
    locationManager.distanceFilter = kCLDistanceFilterNone;

    locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    [locationManager startUpdatingLocation];

    //Latitude and longitude of the current location of the device.
    double lati = locationManager.location.coordinate.latitude;
    double longi = locationManager.location.coordinate.longitude;
    NSLog(@"Latitude = %f", lati);
    NSLog(@"Longitude = %f", longi);

    CLLocation *myLocation = [[CLLocation alloc] initWithLatitude:lati longitude:longi];

    // Create a GMSCameraPosition that tells the map to display the coordinate

    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:lati
                                                            longitude:longi
                                                                 zoom:11.5];

    mapView_ = [GMSMapView mapWithFrame:[[UIScreen mainScreen] bounds] camera:camera];
    mapView_.myLocationEnabled = YES;
    self.view = mapView_;

    // Creates a marker in the center of the map.
    GMSMarker *marker = [[GMSMarker alloc] init];
    marker.position = CLLocationCoordinate2DMake(lati, longi);
    marker.title = @"It's Me";
    marker.snippet = @"My Location";
    marker.map = mapView_;

    [mapView_ addSubview:_btn];
    [mapView_ bringSubviewToFront:_btn];

}
@end

你可以看到,在最后的两行代码中,我把按钮设置为地图视图(mapview)的子视图,并尝试将其置于最前面。但是这并没有起作用。请告诉我我缺少了什么,或者是否有其他方法可以使用某些其他函数来完成此操作。

请查看我创建的storyboard截图,以便更好地理解我在这里尝试做什么。

Storyboard截图

谢谢。


1
把这个已经在这里被问过的问题再发一遍有什么意义呢? - Adil Soomro
5个回答

15

GMSMapViewUIView的子类,因此您可以像其他视图一样添加子视图。

尝试这段代码

UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(mapView_.bounds.size.width - 110, mapView_.bounds.size.height - 30, 100, 20);
button.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin;
[button setTitle:@"Button" forState:UIControlStateNormal];
[mapView_ addSubview:button];

它在GMSMapView的子视图中添加了一个100x20按钮,定位到右下角。我已经测试过,该按钮可以像其他视图一样被触摸。
编辑: 还要将所有代码从-loadView移动到-viewDidLoad中。使用IB创建UI时,-loadView方法不会被调用。有关-loadView的文档说:

如果您使用Interface Builder创建视图并初始化视图控制器,则不应重写此方法。

编辑2: 我认为,当使用Interface Builder创建视图层次结构时,您不能像您正在做的那样重置self.view属性。
请在 -viewDidLoad 中执行此操作。
[self.view addSubview: mapView_];

替代

标签

self.view = mapView_;

如果您将 GMSMapView 传递给 self.view 属性,那么从这一点开始,地图只是控制器中的视图。我认为这就是为什么您看不到 IB 创建的按钮的原因。

我不得不在最后一行进行更改才能使其正常工作。 我将[_mapView addSubview:button];更改为[mapView_ addSubview:button]; - Manas
很抱歉,我不能帮助你,因为我不再使用Interface Builder UI。也许你可以尝试将代码从“-loadView”移动到“-viewDidLoad”。 - Lukas Kukacka
@LukasKukacka:你给我的解决方案可以通过编程方式创建一个按钮,使按钮出现在地图上,但这并不能帮助我返回到以前的屏幕,因为我无法在运行时创建segue。它应该存在于storyboard中,而我在storyboard中创建的按钮没有出现在视图上。请再次检查ViewController.m的最后两行。根据您的建议,我还将代码从-loadView移动到-viewDidLoad。 - MK Singh
@LukasKukacka:我相信你在第二次编辑中提到的理论上是正确的,但当我用[self.view addSubview: mapView_];替换了self.view = mapView_;后,我的程序进入了一些无限循环,屏幕没有从滑块视图切换到地图视图,而且我在函数中放置了一个NSLog命令,它连续打印了5分钟。最后我不得不切换回我的以前的代码。 - Manas
我通过嵌入导航控制器得到了一个替代解决方案,正如我在上面的评论中提到的。 - Manas
显示剩余6条评论

3
我遇到了同样的问题,解决方法很简单,只需覆盖此 UIViewController 方法:
-(void) viewWillAppear:(BOOL)animated 并将您的 UIButton 创建逻辑放在该方法中。 示例:
-(void) viewWillAppear:(BOOL)animated
{
 locationButton = [UIButton buttonWithType:UIButtonTypeCustom];
 locationButton.frame = CGRectMake(0, 30, self.view.frame.size.width/6, self.view.frame.size.height/6);
 [locationButton setImage:[UIImage imageNamed:@"location_enabled.png"] forState:UIControlStateNormal];
 [self.view addSubview:locationButton];
}

3
使用InterfaceBuilder使视图正常显示,并将mapView放置在0索引的子视图中:
mapView_ = [GMSMapView mapWithFrame:self.view.bounds camera:camera];
mapView_.myLocationEnabled = YES;
[self.view insertSubview:mapView_ atIndex:0];

感谢来自这个帖子的Raul Clauss的帮助:thread 您可以自定义地图视图的大小,更改:
mapView_ = [GMSMapView mapWithFrame:_mapHolder.bounds camera:camera];
mapView_.myLocationEnabled = YES;
[_mapHolder insertSubview:mapView_ atIndex:0];

在IB中创建的UIView称为mapHolder。


2
这个问题是因为您尝试使用代码添加地图视图,之前您已经使用界面构建器添加了按钮。当您添加地图视图时,它会添加在视图的顶部,这就是为什么您的按钮没有显示的原因。
您有两个选择来解决这个问题。
第一种方法:
1. 从界面构建器中拖放UIButton并相应地设置约束条件。 2. 然后,在相应的viewController中创建该按钮的outlet。 3. 在将地图视图添加到视图后,粘贴以下代码以将按钮置于顶部: ``` mapViewForScreen.addSubview(self.bottonToAdd) mapViewForScreen.bringSubviewToFront(self.bottonToAdd) ```
完成上述三个步骤后,您可以发现在地图视图上方有一个按钮。

enter image description here

第二种方法
如果您不想使用界面生成器,可以使用以下代码来实现相同的功能。
    var bottonToAdd:UIButton = UIButton()
    bottonToAdd.setTitle("Button To Add", for: .normal)
    bottonToAdd.sizeToFit()
    bottonToAdd.center = mapViewForScreen.center
    bottonToAdd.tintColor = UIColor.blue
    mapViewForScreen.addSubview(bottonToAdd)
    mapViewForScreen.bringSubviewToFront(bottonToAdd)

0
 let mapButton:UIButton = UIButton(frame: CGRect(x:self.view.bounds.width-50, y: 20, width: 40, height: 40)) //Swfit 5
    mapButton.backgroundColor = UIColor.clear
    mapButton.setImage(UIImage(named: "list"), for: UIControl.State.normal)
    mapButton.setImage(UIImage(named: "map"), for: UIControl.State.selected)
    mapButton.addTarget(self, action:#selector(self.mapListClicked), for: .touchUpInside)
    self.view.addSubview(mapButton)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接