动态信息窗口大小ios谷歌地图

时间:2017-06-21 09:50:38

标签: ios objective-c google-maps

我正在谷歌地图上创建自定义信息窗口,如下所示:

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;
}

2 个答案:

答案 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
    }
}