SwiftUI无法捕获MapView的图像

问题描述 投票:0回答:1

我有一个包含地图的SwiftUI应用。我想捕获地图的图像并将该图像显示为另一个视图上的SwiftUI图像。我一直找不到任何文档。我尝试了两种捕获方法,但都不起作用。请参阅下面的扩展。

这是一个简化的示例:

ContentView:

struct ContentView: View {

    @State private var showDetail: Bool = false
    @State private var thumbImage: Image = Image(systemName: "gear")

    var body: some View {
        VStack {
            Text("This is the ContentView")

            if showDetail {
                DetailMapView(thumbImage: $thumbImage)
            }

            if !showDetail {
            Image(systemName: "gear")
                .resizable()
                .frame(width: 200, height: 200)
            }
            Button(action: {
                self.showDetail.toggle()
            }) {
                Text("Tap for Map")
            }
        }
    }
}

和MapView:

struct DetailMapView: UIViewRepresentable {
    typealias UIViewType = MKMapView

    @Binding var thumbImage: Image

    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: DetailMapView

        init(_ parent: DetailMapView) {
            self.parent = parent
        }
    }//coordinator

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.showsUserLocation = true
        mapView.delegate = context.coordinator

        // this does not work - it crashes  
        // let s = mapView.pb_takeSnapshot()
        // self.thumbImage = Image(uiImage: s)

        //this does not work either - it produces lots of console complaints
        let t = mapView.screenshot
        DispatchQueue.main.async {
            self.thumbImage = Image(uiImage: t)
        }

        return mapView
    }
}

extension UIView {

    func pb_takeSnapshot() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, false, UIScreen.main.scale)
        drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image!
    }
}

extension UIView {

    var screenshot: UIImage{
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0)
        guard let context = UIGraphicsGetCurrentContext() else { return UIImage() }
        self.layer.render(in: context)
        guard let screenShot = UIGraphicsGetImageFromCurrentImageContext() else { return UIImage() };
        UIGraphicsEndImageContext()
        return screenShot
    }
}

屏幕截图版本的控制台输出:

[VKDefault] TextureAtlasPage: Atlas page destroyed with outstanding references.: Assertion with expression - _textureRefs == 0 : Failed in file - /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit_Sim/VectorKit-1606.34.10.29.27/src/TextureAtlas.cpp line - 604
[VKDefault] TextureAtlasPage: Atlas page destroyed with outstanding references.: Assertion with expression - _textureRefs == 0 : Failed in file - /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/VectorKit_Sim/VectorKit-1606.34.10.29.27/src/TextureAtlas.cpp line - 604

任何指导将不胜感激。 Xcode 11.4(11E146)

ios xcode mapkit
1个回答
0
投票

对于其他人:这对我有用-忘记上面的扩展名。关键是要用mapViewDidFinishRenderingMap,并且该函数必须位于Coordinator类内。

func mapViewDidFinishRenderingMap(_ mapView: MKMapView, fullyRendered: Bool) {

    //setup whatever region you want to see :mapView.setRegion(region, animated: true)
    let render = UIGraphicsImageRenderer(size: mapView.bounds.size)
    let ratio = mapView.bounds.size.height / mapView.bounds.size.width
    let img = render.image { (ctx) in
        mapView.drawHierarchy(in: CGRect(x: 100, y: 100, width: 300, height: 300 * ratio), afterScreenUpdates: true)
    }
    DispatchQueue.main.async {
        self.parent.thumbImage = Image(uiImage: img)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.