从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的图像,如果我可以在预览中显示它,那就太理想了。
我认为预览无法访问当前位置,因此
MKLookAroundSceneRequest
不知道MKMapItem.forCurrentLocation()
在哪里。
由于制作自己的虚拟对象
MKMapItem
对我来说有点麻烦,我建议只使用需要坐标的MKLookAroundSceneRequest
的其他初始化器。
无需从
#Preview
传入坐标,您只需检测是否处于预览状态。例如使用 Aleš 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)
}
但显然这需要更改大量现有代码。