🤳

SwiftUIでGoogleMapにzoomボタンを追加する

2022/08/20に公開

Androidでは

UiSettings.setZoomControlsEnabled(true)

だけでzoomボタンが地図に追加できますが、iOSではできないらしい...

Zoom Controls In Google Maps
Google Maps SDK for iOS doesn’t offer inbuilt zoom controls (but the Android SDK does). You will want to write your own logic instead.

https://www.webnexs.com/blog/kb/use-google-maps-sdk-ios-using-swift/

公式に無いなら無くても良さそうですが、Androidと揃えたい感じもするので自分でなんとかする


Stepperを利用する

それっぽいボタンはSwiftUIにある(Stepper)のでひとまずそれを使ってみます

mapのzoomする値をボタンをタップして増減させる必要があります。だいたい0.5刻みで増減させればそれっぽくなりそう

ContentViewにStepperを実装します

struct ContentView: View {
    @State private var zoomValue: Float = 0.0

    var body: some View {
        ZStack(alignment: .bottomTrailing) {
            MapView(zoomValue: $zoomValue).ignoresSafeArea()
            Stepper(value: $zoomValue, in: 0...2, step: 0.5, label: {})
                .padding()
        }
    }
}

↓これだけで、ボタンをタップすると0から2の間で0.5刻みで増減させることができます

Stepper(value: $zoomValue, in: 0...2, step: 0.5, label: {})

MapViewで実際に地図の拡大縮小を行います
デフォルトのzoom値に対してzoomValueを加算して新しいzoom値でtoZoomしてあげる感じです

struct MapView: UIViewRepresentable {
    ...
    ...
    let mapView = GMSMapView(frame: .zero)
    @State var locationManager = CLLocationManager()
    @Binding var zoomValue: Float
    ...
    ...
    func updateUIView(_ mapView: GMSMapView, context: Context) {
        mapView.animate(toZoom: 15.0 + zoomValue)
    }
}

zoomができるようになりました〜

ボタンから自前で実装する

Stepperでも十分ですがもうちょっと良い感じのzoomボタンにしたい...

Button(action: { zoomValue += 0.5 }) {
	Image(systemName: "plus.circle.fill")
		.resizable()
                .foregroundColor(.blue)
}
.frame(width: 30, height: 30)
.disabled(isZoomButtonDisable)
.opacity(isZoomButtonDisable ? 0.5 : 1.0)

ImageはSF Symbolsからよさそうなのを選びました

https://developer.apple.com/sf-symbols/

もっといいやり方はあると思うけどいったんはこれでやると全体はこうなります(MapViewはStepperのときと同じ)

struct ContentView: View {
    @State private var zoomValue: Float = 0.0
    @State private var isZoomButtonDisable = false

    var body: some View {
        ZStack(alignment: .bottomTrailing) {
            MapView(zoomValue: $zoomValue).ignoresSafeArea()
            VStack {
                Button(action: { zoomValue += 0.5 }) {
                    Image(systemName: "plus.circle.fill")
                        .resizable()
                        .foregroundColor(.blue)
                }
                .frame(width: 30, height: 30)
                .disabled(isZoomButtonDisable)
                .opacity(isZoomButtonDisable ? 0.5 : 1.0)

                Button(action: { zoomValue -= 0.5 }) {
                    Image(systemName: "minus.circle.fill")
                        .resizable()
                        .foregroundColor(.blue)
                }
                .frame(width: 30, height: 30)
                .disabled(zoomValue == 0.0)
                .opacity(zoomValue == 0.0 ? 0.5 : 1.0)
            }
            .padding(.trailing, 10)
        }
    }
}

なんかダサい気もするけどできた〜

終わりに

???「そこに無ければ無いですね」

GoogleMapいろいろあそべそう( 'o' )!!

参考

https://www.webnexs.com/blog/kb/use-google-maps-sdk-ios-using-swift/
https://developer.apple.com/documentation/swiftui/stepper
https://developer.apple.com/sf-symbols/
https://github.com/mimimi-miOmi-mimi/ios_google_map_demo

Discussion