不能将谷歌地图 GMSMapView 放在主视图的子视图中?
Posted
技术标签:
【中文标题】不能将谷歌地图 GMSMapView 放在主视图的子视图中?【英文标题】:Cannot put a google maps GMSMapView in a subview of main main view? 【发布时间】:2013-03-03 07:20:44 【问题描述】:我正在努力解决这个问题!
我想将谷歌地图GMSMapView
添加到UIView
中,这只是我的ViewController
的主要UIView
的一部分。
应该很简单...我用情节提要创建了一个我想要大小的UIView
,并将它放在主UIView
中。
来自接口文件的片段:
@interface MapViewController : UIViewController <CLLocationManagerDelegate>
@property(nonatomic) IBOutlet GMSMapView *mapView;
在主UIView
中使用与此UIView
链接的mapView。
我在实现中做了什么:
@synthesize mapView = _mapView;
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683
longitude:151.2086
zoom:10];
_mapView = [GMSMapView mapWithFrame:_mapView.bounds camera:camera];
_mapView.myLocationEnabled = YES;
这应该可行,不是吗? 我得到的是我的内部 UIView 是空的。
如果我按照 google 的入门指南 Google Map Integration Document 实例化地图,它可以工作,但它会将地图分配给 MAIN UIView,这是另一回事。
我什至尝试将情节提要中的 mapView 的类从 UIView
更改为 GMSMapView
。
地图显示在内部视图中,但它以一种奇怪的方式初始化
-
系统抛出错误提示
“无法制作完整的帧缓冲区”
并大大减慢了视图的加载速度(在模拟器上需要 2-3 秒)
-
在
viewDidLoad
方法中完成的任何相机更改中,地图都没有响应。
有什么建议吗?
我在 *** 上阅读了一些帖子,但找不到有效的解决方案 :(
【问题讨论】:
【参考方案1】:根据其他答案,这里有三种实际可行的方法。
-
在 XIB 上放置一个视图,并在 XIB builder 中将其类更改为 GMSMapView。请参见下面的 *map1。或者...
全部编码。将地图添加为主视图的子视图。请参见下面的 *map2。或者...
将地图添加为已在 XIB 中具有插座的另一个子视图的子视图。 *下面的地图3。
.h
@interface GPViewController : UIViewController
@property (strong, nonatomic) IBOutlet GMSMapView *map1;
@property (strong, nonatomic) IBOutlet UIView *plainViewOnXIBHoldsMap3;
@end
.m
- (void)viewDidLoad
[super viewDidLoad];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.0
longitude:151.20
zoom:6];
/* Option 1. view on XIB is class GSMMapView */
self.map1.camera = camera;
/* Option 2. add a map as a subview */
GMSMapView *map2 = [GMSMapView mapWithFrame:CGRectMake(0, 0, 100, 100) camera:camera];
[self.view addSubview:map2];
/* Option 3. add a map to a subview already on the XIB */
GMSMapView *map3 = [GMSMapView mapWithFrame:self.plainViewOnXIBHoldsMap3.bounds camera:camera];
[self.plainViewOnXIBHoldsMap addSubview:map3];
【讨论】:
选项 1 工作正常。最重要的是,不要手动设置你的地图框架,让它从 XIB 中获取,否则你会覆盖你的委托方法。 选项 1 不起作用我不知道问题所在,因为我是初学者。 为什么我之前没有找到这个解决方案,它解决了我的问题,当然我也做了一些其他的编码,但它给了我前进的道路...... +1 如果您遵循 Google 的入门指南,请不要忘记从代码中删除空的 loadView 方法,否则这些选项都不起作用。 如果有人想使用option 2
中提到的自定义框架以编程方式创建GMSMapView
,请使用loadView
方法而不是viewDidload
,并且不要忘记添加[super loadView];
然后它会工作的!【参考方案2】:
已签出并开始在 Swift 2.0 中使用 cloudsurfin 提供的所有三个选项。为那些在 Swift 2.0 中面临同样问题的人翻译他的答案:
Option1 - 在 XIB 上放置一个视图,并在 XIB builder 中将其类更改为 GMSMapView。
Option2 - 全部编码。将地图添加为主视图的子视图。
Option3 - 将地图添加为现有 UIView 子视图的 GMSMapView 子视图。
Option1在XIB中的准备说明:
1) 为您的视图设置一个类:
2) 不要忘记在代码中将视图与插座连接起来:
import UIKit
import GoogleMaps
class MapViewController: UIViewController
@IBOutlet weak var map1 : GMSMapView!
@IBOutlet weak var map3 : UIView!
override func viewDidLoad()
super.viewDidLoad()
let camera = GMSCameraPosition.cameraWithLatitude(53.9,
longitude: 27.5667, zoom: 6)
// Option 1. view on XIB is class GSMMapView
self.map1.camera = camera;
// Option 2. add a map as a subview
let map2 = GMSMapView.mapWithFrame(CGRectMake(0, 64, 320, 460), camera:camera)
self.view.addSubview(map2)
// Option 3. add a map to a subview of UIView class that is already on the XIB
let map3 = GMSMapView.mapWithFrame(self.plainViewOnXIBHoldsMap3.bounds, camera:camera)
self.plainViewOnXIBHoldsMap3.addSubview(map3)
希望这篇笔记对某人有所帮助:)
【讨论】:
它在 Swift 3 中对我不起作用。有什么变化吗??【参考方案3】:我的建议:
-
将故事板中的 UIView 作为 UIView 实例变量而不是 GMSMapView 链接到头文件
将 mapWithFrame:camera: 方法更改为链接的 UIView 的边界
在 viewDidLoad: 方法的最后,将 UIView 实例变量设置为您的 GMSMapView,或者添加一个子视图。我也遇到过这个问题,而且通常可以解决这个问题。
.h
@interface MapViewController: UIViewController <CLLocationManagerDelegate>
IBOutlet UIView *mapViewOnSreen;
.m
- (void)viewDidLoad
[super viewDidLoad];
// Do any additional setup after loading the view.
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.8683
longitude:151.2086
zoom:10];
_mapView = [GMSMapView mapWithFrame:mapViewOnScreen.bounds camera:camera];
_mapView.myLocationEnabled = YES;
mapViewOnScreen = _mapView
//OR [self.view addSubview:_mapView];
//OR [mapViewOnScreen addSubview:_mapView]; <--This worked for me
*编辑:我使用 IB 在主视图中创建了一个小的 UIView。我按照列出的步骤操作,当我设置 [mapViewOnScreen addSubview:_mapView]; 时,我能够在小 UIView 中查看地图;
【讨论】:
mapWithFrame:mapViewOnScreen.bounds 在我的例子中被设置为 CGRectZero。来自谷歌的教程。【参考方案4】:你可以通过 IB 做到这一点
.h
@property (weak, nonatomic) IBOutlet GMSMapView *theMapView;
.m
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.868
longitude:151.2086
zoom:12];
//This next line is not needed if you have a GMSMapView outlet
//self.theMapView = [GMSMapView mapWithFrame:self.theMapView.frame camera:camera];
self.theMapView.camera=camera;
self.theMapView.mapType = kGMSTypeSatellite;
self.theMapView.delegate=self;
【讨论】:
【参考方案5】:我只是因为忘记添加这一行而出现黑屏:
[super loadView];
【讨论】:
【参考方案6】:对于 Swift 3,如果您将 GMSMapView
子类化
-
将
UIView
添加到故事板中的UIViewController
-
将类更改为
GMSMapView
而不是 UiView
在UIViewController
类中创建引用
@IBOutlet weak var mapView: GMSMapView!
当您进行子类化时,您不需要使用文档中提到的 GMSMapView.map(withFrame: CGRect.zero, camera: camera)
。只需按如下方式加载地图
let camera = GMSCameraPosition.camera(withLatitude: 51.50, longitude: -0.076, zoom: 10.0)
mapView.camera = camera
为了添加标记
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: 51.50, longitude: -0.076)
marker.title = "London"
marker.snippet = "UK"
marker.map = mapView
一起作为一个函数
override func viewDidLoad()
super.viewDidLoad()
load()
func load()
//map
let camera = GMSCameraPosition.camera(withLatitude: 51.50, longitude: -0.076, zoom: 10.0)
mapView.camera = camera
//marker
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: 51.50, longitude: -0.076)
marker.title = "London"
marker.snippet = "UK"
marker.map = mapView
【讨论】:
节省了几个小时,伙计。谢谢! :) 非常感谢。我花了好几个小时才找到正确的位置。【参考方案7】:我花了大约半个小时试图让它工作,然后我发现我用了错误的方法。谷歌入门示例告诉您将其放入 - (void)loadView 但如果您这样做,您会得到黑屏或全屏地图。你需要把它放在 - (void)viewDidLoad 中。然后就可以了。
【讨论】:
天哪!太棒了。【参考方案8】:在身份检查器中将 UIVIEW 类设置为 GMSMapView。
然后从中制作一个 IBOutlet :D 并且它是工作 :P
【讨论】:
【参考方案9】:(void)viewDidLoad
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:-33.86
longitude:151.20
zoom:14];
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(-33.86, 151.20);
marker.title = @"Sydney";
marker.snippet = @"Australia";
marker.map = self.mapContainerView;
//set the camera for the map
self.mapContainerView.camera = camera;
self.mapContainerView.myLocationEnabled = YES;
【讨论】:
【参考方案10】:按照 2017 年 9 月的 Swift 谷歌教程
我通过像这样将代码放入 viewDidLoad 来修复
var mapView: GMSMapView!
override func viewDidLoad()
super.viewDidLoad()
// Create a GMSCameraPosition to display the initial center of the map
let camera = GMSCameraPosition.camera(withLatitude: 23.885942, longitude: 45.079162, zoom: 5.1)
// Set the frame size , don't forget to replace "<CustomFrame>" with the required frame size
mapView = GMSMapView.map(withFrame: "<CustomFrame>", camera: camera)
// Add the map to any view here
view.addSubview(mapView) //or customView.addSubview(mapView)
【讨论】:
以上是关于不能将谷歌地图 GMSMapView 放在主视图的子视图中?的主要内容,如果未能解决你的问题,请参考以下文章