问题描述
在我的应用程序中,用户可以添加图像(地图),然后向该图像添加图钉(小图像+附加注释)。该地图位于滚动视图中。添加引脚等效果很好,但有一个例外:在人像模式下的iPhone(或更精确的traitcollection == .compact)上,我无法使引脚居中并略微缩小。所有这些都在自定义的splitview控制器中;在左视图控制器中注释,在右视图控制器中映射(图像+引脚)。
在横向使用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)
}