从 UIViewControllerRepresentable 中按下的按钮导航到 SwiftUI 视图

时间:2021-05-28 02:09:40

标签: swiftui swiftui-navigationview uiviewcontrollerrepresentable

我正在使用 Swiftui 列表来显示任务。每个任务都有一个位置。当您单击列表行时,我正在使用 NavigationLink 导航到详细信息页面。

我正在使用 UIViewControllerRepresentable 创建一个地图视图,其中所有任务位置都在地图上进行了注释。我不得不使用 UIKit 以便您可以与注释进行交互。我设置了一个委托,当用户单击地图注释附件时会触发该委托。

目的:当调用委托函数时,我想传回用于导航到详细信息页面的 taskid,例如单击列表行时:

Chevron right calls delegate

List View

我从列表中导航的方式:

ForEach(tasksToDisplayInList, id: \.id) { task in
    NavigationLink(
        destination: TaskDetailsView(taskId: task.id, title: task.title)) 
    {
        TaskListRow(task: task)
            .padding(.trailing, 5)
            .foregroundColor(.textDefault)
    }
}

传回按下的任务id的任务列表映射UIViewControllerRepresentable:

struct TaskListMap: UIViewControllerRepresentable {
    typealias UIViewControllerType = TaskListMapController
    
    @Binding var annotations: [TaskAnnotation]
    
    class Coordinator: TaskListMapDelegate {
        func didPressMoreDetail(_ mapController: TaskListMapController, for annotation: TaskAnnotation) {
            // TaskAnnotation contains the taskId
            // Navigate here somehow?
        }
        
        var parent: TaskListMap
        
        init(_ parent: TaskListMap) {
            self.parent = parent
        }
    }
    
    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> TaskListMapController {
        let mapController = TaskListMapController(annotations: annotations)
        mapController.delegate = context.coordinator
        return mapController
    }
    
    func updateUIViewController(_ uiViewController: TaskListMapController, context: Context) {
        if annotations.count != uiViewController.mapView.annotations.count {
            uiViewController.mapView.removeAnnotations(uiViewController.mapView.annotations)
            uiViewController.mapView.addAnnotations(annotations)
        }
    }
}

1 个答案:

答案 0 :(得分:0)

作为一种解决方法,这似乎对我的目的很有效:

// # TaskListMapView.swift (inside the coordinator)
    
class Coordinator: TaskListMapDelegate {
    var parent: TaskListMap
        
    init(_ parent: TaskListMap) {
        self.parent = parent
    }

    func didPressMoreDetail(_ mapController: TaskListMapController, for annotation: TaskAnnotation) {
            
        // Push the navigation with a hosting controller

        let detailsView = UIHostingController(rootView: TaskDetailsView(taskId: annotation.taskId, title: annotation.title ?? ""))

        mapController.navigationController?.pushViewController(detailsView, animated: true)

     }
}