mapbox-maps-ios
mapbox-maps-ios copied to clipboard
Setting camera bounds with padding fails [v11]
Environment
- Xcode version: 15.2
- iOS version: 17.0
- Devices affected: iOS Simulator
- Maps SDK Version: Reproduced on 11.2.0-rc1 and 11.1.0
Observed behavior and steps to reproduce
When setting the camera to a coordinate bounds with padding, the camera does not zoom out to encompass the provided bounds.
To reproduce, run this example with Mapbox >= 11.0.0 and click the Change
button repeatedly:
CameraAnimationExample.swift
import UIKit
import MapboxMaps
final class CameraAnimationExample: UIViewController, ExampleProtocol {
private var mapView: MapView!
private var cameraOptions: CameraOptions!
private var flag = 0
override func viewDidLoad() {
super.viewDidLoad()
mapView = MapView(frame: view.bounds)
mapView.ornaments.scaleBarView.isHidden = true
try? mapView.mapboxMap.setProjection(.init(name: .mercator))
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(mapView)
let button = UIButton(type: .roundedRect)
button.backgroundColor = .white
button.setTitle("Change", for: .normal)
button.layer.position = .init(x: 100, y: 100)
button.frame.size = .init(width: 200, height: 40)
button.addTarget(self, action: #selector(onClick), for: .touchUpInside)
view.addSubview(button)
mapView.mapboxMap.onMapLoaded.observeNext { _ in
self.onClick()
}
}
@objc func onClick() {
switch flag {
case 0:
let padding = UIEdgeInsets(
top: 0,
left: 0,
bottom: 500,
right: 0
)
cameraOptions = CameraOptions(
center: CLLocationCoordinate2D(
latitude: 41.888579,
longitude: -87.804039
),
padding: padding,
zoom: 14,
bearing: 0,
pitch: 0
)
print("Camera 1 | Padding \(padding.top + padding.bottom), map height \(mapView.bounds.height)")
case 1:
let padding = UIEdgeInsets(
top: 0,
left: 0,
bottom: 500,
right: 0
)
cameraOptions = mapView.mapboxMap.camera(
for: CoordinateBounds(
southwest: CLLocationCoordinate2D(
latitude: 41.87726211032818,
longitude: -87.80420963106079
),
northeast: CLLocationCoordinate2D(
latitude: 41.880369537640505,
longitude: -87.80199949078224
)
),
padding: padding,
bearing: nil,
pitch: nil,
maxZoom: nil,
offset: nil
)
print("Camera 2 | Padding \(padding.top + padding.bottom), map height \(mapView.bounds.height)")
default:
break
}
mapView.camera.ease(to: cameraOptions, duration: 1)
flag += 1
if flag == 2 {
flag = 0
}
}
}
Expected behavior
On repeat click, the camera should alternatively ease between a center coordinate and a slightly zoomed out bounds, both bottom-padded.
Actual behavior
The camera moves laterally to the approximate bounding box, but the zoom does not change. The following seemingly contradictory data prints to the console:
Camera 1 | Padding 500.0, map height 852.0 Camera 2 | Padding 500.0, map height 852.0 [Warning, maps-core]: {}[General]: Unable to calculate camera for given bounds/geometry, padding is greater than map's width or height.
Notes / preliminary analysis
- This bug appears to happen on all v11. On v10, it works correctly.
- Using
try camera(for:camera:coordinatesPadding:maxZoom:offset:)
has the same issue, but it throws instead of quietly logging to the console. - Lowering the padding to total a smaller amount produces a strange set of bounds:
-
>=353
: Zoom does not change, as shown in the v11 video. -
=352
: Suddenly zooms way out to bound around a very large area. -
<=351
: As padding gets closer to zero, zoom increases until eventually settles at the correct value when padding is 0.
-
Additional links and references
The above example behaves correctly on v10:
https://github.com/mapbox/mapbox-maps-ios/assets/2423291/d2e935cd-d6f5-4ee4-952f-b00a0858f08f
but fails on v11:
https://github.com/mapbox/mapbox-maps-ios/assets/2423291/4ca88720-6bae-4ca4-8ad5-7f824ed2fa57