我正在谷歌地图上创建自定义信息窗口,如下所示:
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"InfoView" owner:self options:nil];
InfoView *mainView = [subviewArray objectAtIndex:0];
UIView *subview = mainView.subviews[0];
//setup content
return subview;
这种方式工作正常,但我无法添加任何约束,因为它填满了整个屏幕并变为空白。所以我决定不用autolayout这样做。
我的内容是一个低于另一个的标签。在相同的情况下,文本不能适合单行,然后标签框架应该增加。同时,还必须增加整个视图框,并且必须正确地偏移下面的视图。我已经做了一个方法来做到这一点,一切都在变化,除了信息窗口视图框架本身。在日志中,我可以看到框架已更改,但在屏幕上,它具有原始大小,文本在其外部。
我甚至尝试过更改信息窗口框架但仍然没有效果 - 它根本没有变化。
我也尝试过调用[subview layoutIfNeeded]
和[subview layoutSubviews]
。
那么,如何制作动态尺寸的信息窗口?
编辑:
@Milan要求的整个代码:
- (UIView *_Nullable) mapView:(GMSMapView *)mapView markerInfoContents: (GMSMarker *)marker {
NSArray *subviewArray = [[NSBundle mainBundle] loadNibNamed:@"PortView" owner:self options:nil];
PortView *mainView = [subviewArray objectAtIndex:0];
UIView *subview = mainView.subviews[0];
mainView.frame = CGRectMake(mainView.frame.origin.x, mainView.frame.origin.y, mainView.frame.size.width, mainView.frame.size.height + 40) //increase frame size doesn't work
mainView.titleLabel.text = portSzukany.name;
return subview;
}
答案 0 :(得分:2)
您需要实现GMSMapViewDelegate并从以下方法返回信息视图:
- (UIView *GMS_NULLABLE_PTR)mapView:(GMSMapView *)mapView markerInfoWindow:(GMSMarker *)marker;
根据方法的描述,"返回的UIView在任一维度上的边界不得超过500个点。"
答案 1 :(得分:0)
当我遇到这个问题时,我找到了更新infoWindow框架的唯一方法:解除信息窗口并再次显示:
let m = mapView?.selectedMarker
mapView?.selectedMarker = nil
mapView?.selectedMarker = m
或者您可以使用SMCalloutView,它与Google地图兼容。
我认为Google地图不会使用系统布局进行渲染。它使用OpenGL或其他东西。
完整的源代码(它的代码很快,我希望这对你来说不会有问题)
import GoogleMaps
class GMapsViewController: UIViewController {
let CalloutYOffset:CGFloat = 50.0
var mapView = GMSMapView.map(
withFrame: CGRect.zero,
camera: GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 6)
),
infoWindowWidth:CGFloat = 0
override func viewDidLoad() {
super.viewDidLoad()
infoWindowWidth = UIApplication.shared.keyWindow?.frame.size.width ?? 0 - 30
//maps
mapView.isMyLocationEnabled = true
mapView.delegate = self
self.view = mapView
//markers
let marker1 = GMSMarker(position: CLLocationCoordinate2DMake(-33.86, 151.20))
marker1.title = "Sydney"
marker1.snippet = "Custom"
marker1.map = mapView
mapView.selectedMarker = marker1
updateInfoWIndowText()
}
var infoWindowText = "tqweqweqweqweqwe"
func updateInfoWIndowText(){
DispatchQueue.main.asyncAfter(deadline: (DispatchTime.now() + .milliseconds(2000)), execute: {
print("UPDATE INFO WINDOW TEXT")
self.infoWindowText = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
weak var mapView = self.mapView
//dismissing info window and showing it
let m = mapView?.selectedMarker
mapView?.selectedMarker = nil
mapView?.selectedMarker = m
})
}
}
extension GMapsViewController:GMSMapViewDelegate {
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
let stackView = UIStackView(frame: CGRect(x: 0, y: 0, w: infoWindowWidth, h: 0))
stackView.axis = .vertical
for _ in 0...3 {
let lab = UILabel()
lab.numberOfLines = 0
lab.text = infoWindowText
lab.backgroundColor = UIColor.red
stackView.addArrangedSubview(lab)
}
stackView.addConstraint(NSLayoutConstraint(
item: stackView,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1.0,
constant: infoWindowWidth))
stackView.h = stackView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
return stackView
}
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
mapView.selectedMarker = marker
return true
}
}