缩放到 iPhone 滚动视图上的位置(纵向);不太对

Zoom to location on scrollview on iPhone (portrait); not quite right

在我的应用程序中,用户可以添加图像(地图),然后向该图像添加图钉(小图像 + 附注)。地图在滚动视图中。添加图钉等工作正常,有一个小例外:在纵向模式的 Iphone 上(或更精确的 traitcollection == .compact)我无法让图钉居中并缩小一点。所有这些都在一个自定义的 splitview 控制器中;左边的笔记 viewcontroller,右边的地图(图片 + 图钉)viewcontroller。

在横向 iPad/iPhone 上,通过调用以下方法可以正常工作:

  mapImageScrollView.zoom(to: mapImageLocationPin!.frame, animated: false)
  mapImageScrollView.setZoomScale(1.0, animated: true)

结果如下

在纵向模式下的 iPhone 上,用户必须单击双箭头按钮才能使用地图向右导航 viewcontroller。使用与上面相同的代码行将导致地图被放大,但 NOT 以图钉为中心。 我能得到的最好的方法是使用以下代码(请注意,要使其正常工作,我必须在 之前设置 Zoomscale 我缩放!)

    mapImageScrollView.setZoomScale(0.85, animated: false)
    mapImageScrollView.zoom(to: mapImageLocationPin!.frame, animated: false)

这会导致居中,但不会缩小

我认为这是由于在第二种情况下正确的 viewcontroller 尚未出现(只有在用户点击双箭头按钮后才会出现),但我似乎找不到更好的解决方案.. .

感谢任何帮助!

我用来将图钉添加到地图的代码:

private func addMapImageLocationPin() {
        if let location = annotation?.location {
            //Activate the corresponding Map Image and update picker
            selectedMapImage = location.map
            mapImagePickerView.selectRow(mapImagesController.getRowFor(location.map), inComponent: 0, animated: true)
            
            //Instantiate new Pin with annotation
            mapImageLocationPin = MapImageLocationPin(with: annotation!, andMapImageSize: mapImageView.image!.size)
            mapImageView.addSubview(mapImageLocationPin!)
            
            //Desired height and width
            let desiredWidth: CGFloat = 160
            let desiredHeight: CGFloat = 80
            
            //compensate for scrollView zoomscale, but never bigger than desired width & height!
            let minZoomScale = mapImageScrollView.minimumZoomScale
            let width = min(desiredWidth, desiredWidth / minZoomScale)
            let height = min(desiredHeight, desiredHeight / minZoomScale)
            
            //center the pin image horizontal on location
            let y = location.coordinateY
            let x = location.coordinateX - (width / 2)
            
            //position (frame) the pin
            mapImageLocationPin?.frame = CGRect(x: x, y: y, width: width, height: height)
            
            //zoom to the pin, different approach for smaller screen sizes
            if traitCollection.horizontalSizeClass == .compact {
                mapImageScrollView.setZoomScale(0.85, animated: false)
                mapImageScrollView.zoom(to: mapImageLocationPin!.frame, animated: false)
            } else {
                mapImageScrollView.zoom(to: mapImageLocationPin!.frame, animated: false)
                mapImageScrollView.setZoomScale(1.0, animated: true)
            }
        }
    }

在布局周期的什么时候调用 addMapImageLocationPin?如果在某些情况下子视图没有立即加载,那么您需要确保在主视图布局后调用定位代码,例如 viewDidAppear:

   override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        mapImageScrollView.zoom(to: mapImageLocationPin!.frame, animated: false)
    }