xcode SwiftUI预览宏:如何提供私有状态属性值以供预览使用

fgw7neuy  于 2023-11-21  发布在  Swift
关注(0)|答案(1)|浏览(170)

从Xcode 15开始,它涉及预览宏。
我用MapKit创建了一个简单的应用程序来学习它。

struct LocationDetailsView: View {
    @Binding var mapSelection: MKMapItem?
    @Binding var show: Bool
    @State private var lookAroundScene: MKLookAroundScene?
    @Binding var getDirections: Bool
    
    var body: some View {
        VStack {
            HStack {
                VStack(alignment: .leading) {
                    Text(mapSelection?.placemark.name ?? "")
                        .font(.title2)
                        .fontWeight(.semibold)
                    
                    Text(mapSelection?.placemark.title ?? "")
                        .font(.footnote)
                        .foregroundStyle(.gray)
                        .lineLimit(2)
                        .padding(.trailing)
                }
                        
                Spacer()
                
                Button {
                    show.toggle()
                    mapSelection = nil
                } label: {
                    Image(systemName: "xmark.circle.fill")
                        .resizable()
                        .frame(width: 24, height: 24)
                        .foregroundStyle(.gray, Color(.systemGray5))
                }
            }
            .padding(.init(top: 40, leading: 20, bottom: 0, trailing: 20))
            
            if let scene = lookAroundScene {
                LookAroundPreview(initialScene: scene)
                    .frame(height: 200)
                    .cornerRadius(12)
                    .padding()
            } else {
                ContentUnavailableView("No preview available", systemImage: "eye.slash")
            }
            
            HStack(spacing: 24) {
                Button {
                    if let mapSelection {
                        mapSelection.openInMaps()
                    }
                } label: {
                    Text("Open in Maps")
                        .font(.headline)
                        .foregroundColor(.white)
                        .frame(width: 170, height: 48)
                        .background(.green)
                        .cornerRadius(12)
                }
                
                Button {
                    getDirections = true
                    show = false
                } label: {
                    Text("Get Directions")
                        .font(.headline)
                        .foregroundColor(.white)
                        .frame(width: 170, height: 48)
                        .background(.blue)
                        .cornerRadius(12)
                }
            }
            .padding(.horizontal)
        }
        .onAppear {
            print("DEBUG: Did call on appear")
            fetchLookAroundPreview()
        }
        .onChange(of: mapSelection) { oldValue, newValue in
            print("DEBUG: Did call on change")
            fetchLookAroundPreview()
        }
        .padding()
    }
}

extension LocationDetailsView {
    func fetchLookAroundPreview() {
        if let mapSelection {
            lookAroundScene = nil
            Task {
                let request = MKLookAroundSceneRequest(mapItem: mapSelection)
                lookAroundScene = try? await request.scene
                print("DEBUG: lookAroundScene \(lookAroundScene)")
            }
        }
    }
}

#Preview {
    LocationDetailsView(
        mapSelection: .constant(MKMapItem.forCurrentLocation()),
        show: .constant(true) ,
        getDirections: .constant(false)
    )
}

字符串
在预览idk中如何提供lookAroundScene属性值给它,请给予我一些建议。顺便说一句,这个lookAroundScene会显示一个关于当前mapSelection的图像,如果我能在预览中显示它就太理想了。

根据Sweeper的回答进行更新


的数据

vc9ivgsu

vc9ivgsu1#

我不认为预览可以访问当前位置,所以MKLookAroundSceneRequest不知道MKMapItem.forCurrentLocation()在哪里。
由于制作你自己的虚拟MKMapItem对我来说有点太麻烦了,我建议只使用MKLookAroundSceneRequestother initialiser,它需要一个坐标。
而不是从#Preview传递坐标,你可以只detect whether you are in a preview。例如,使用Alejandro Kocur的答案:

let request = !isPreview ? 
    MKLookAroundSceneRequest(mapItem: mapSelection) :
    MKLookAroundSceneRequest(coordinate: CLLocationCoordinate2D(latitude: 51.5069819, longitude: -0.0889239)) // somewhere in London

字符串
如果你愿意,你仍然可以从#Preview { }中传入一个坐标-例如,在你的视图中添加一个额外的let来存储在预览中使用的坐标,或者使用这样的枚举作为mapSelection的类型:

enum MapSelection {
    case mapItem(MKMapItem)
    case coordinate(CLLocationCoordinate2D)
}


但很明显,这将涉及到更改大量现有代码。

相关问题