2
1

More than 1 year has passed since last update.

SwiftUI BindingのあるViewのプレビューを正しく表示する

Last updated at Posted at 2023-01-20

概要

例えば、地図を表示するViewをSwiftUIで構築します。
このViewは地図と、現在地を示す位置情報をテキストで表示します。
地図はMapKitを使って、Mapで表示します。

Mapのinitの形式にはMKCoordinateRegionMKMapRectを使いますが、いずれの型式でもBindingでの指定が必要になります。
構築するViewが外から@Bindingの形でパラメータを受け取る形の場合、PreviewにもBindingに指定する@Stateなどの値が必要になります。

Stateを用意せず、プレビューで.constantで固定のMKCoordinateRegionを入れておけばビルドとしては動きますが、プレビューとしては、地図を動かしても位置情報テキスト部分の値が変わりません。

修正前.gif

正しくBindingをPreviewで動かす

動的にBindingの値を動かしたい場合、Preview内部で中間のViewを用意し、そのViewで@Stateを使ってMapViewを実装することにより、プレビューでも値が追従されることを確認可能になります。

修正後.gif

この中間Viewの名前をShimとしていますが、この命名及びコードはWWDC20のStructure your app for SwiftUI previewsを参考にしています。

import SwiftUI
import MapKit

struct MapView: View {
    @Binding var coordinateRegion: MKCoordinateRegion
    
    var body: some View {
        VStack {
            Text("\(coordinateRegion.center.latitude.description)")
            Map(coordinateRegion: $coordinateRegion)
        }
    }
}

struct MapView_Previews: PreviewProvider {
    struct Shim: View {
        @State private var coordinateRegion = MKCoordinateRegion(center: .init(latitude: 35,
                                                                               longitude: 139),
                                                                 span: .init(latitudeDelta: 0.01,
                                                                             longitudeDelta: 0.01))
        var body: some View {
            MapView(coordinateRegion: $coordinateRegion)
        }
        
    }
    static var previews: some View {
        Shim()
    }
}

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1