Can't drag down/dismiss UIColorPickerViewController - swiftui

I am displaying a UIColorPickerViewController as a sheet using the sheet() method, everything works fine but I can't drag down/dismiss the view anymore.
import Foundation
import SwiftUI
struct ColorPickerView: UIViewControllerRepresentable {
private var selectedColor: UIColor!
init(selectedColor: UIColor) {
self.selectedColor = selectedColor
}
func makeUIViewController(context: Context) -> UIColorPickerViewController {
let colorPicker = UIColorPickerViewController()
colorPicker.selectedColor = self.selectedColor
return colorPicker
}
func updateUIViewController(_ uiViewController: UIColorPickerViewController, context: Context) {
// Silent
}
}
.sheet(isPresented: self.$viewManager.showSheet, onDismiss: {
ColorPickerView()
}
Any idea how to make the drag/down dismiss gesture works?
Thanks!

Ran into the same problem when trying to build a color picker similar to above. What worked was "wrapping" the color picker in a view with a Dismiss button. And also discovered that the bar at the top of the view would allow the picker to now be dragged down and away. Below is my wrapper. (One could add more features such as a title to the bar.)
struct ColorWrapper: View {
var inputColor: UIColor
#Binding var isShowingColorPicker: Bool
#Binding var selectedColor: UIColor?
var body: some View {
VStack {
HStack {
Spacer()
Button("Dismiss", action: {
isShowingColorPicker = false
}).padding()
}
ColorPickerView(inputColor: inputColor, selectedColor: $selectedColor)
}
}
}
And for completeness, here is my version of the color picker:
import SwiftUI
struct ColorPickerView: UIViewControllerRepresentable {
typealias UIViewControllerType = UIColorPickerViewController
var inputColor: UIColor
#Binding var selectedColor: UIColor?
#Environment(\.presentationMode) var isPresented
func makeUIViewController(context: Context) -> UIColorPickerViewController {
let picker = UIColorPickerViewController()
picker.delegate = context.coordinator
picker.supportsAlpha = false
picker.selectedColor = inputColor
return picker
}
func updateUIViewController(_ uiViewController: UIColorPickerViewController, context: Context) {
uiViewController.supportsAlpha = false
}
func makeCoordinator() -> Coordinator {
return Coordinator(parent: self)
}
class Coordinator: NSObject, UINavigationControllerDelegate, UIColorPickerViewControllerDelegate {
var parent: ColorPickerView
init(parent: ColorPickerView) {
self.parent = parent
}
func colorPickerViewControllerDidFinish(_ viewController: UIColorPickerViewController) {
parent.isPresented.wrappedValue.dismiss()
}
func colorPickerViewController(_ viewController: UIColorPickerViewController, didSelect color: UIColor, continuously: Bool) {
parent.selectedColor = color
// parent.isPresented.wrappedValue.dismiss()
}
}
}

Related

SwiftUI UIIMagePickerController Find/Search Field Strange Behaviour

I'm using a UIImagePickerController to select an image from the user's photo library. All works fine except when the user taps on the field with the magnifying glass icon to search the library. Sometimes it dismisses ImagePicker, other times it does nothing and occasionally it works as expected... any ideas?
Code to display the sheet:
Button(action: {}) {
ZStack {
Image(systemName: "photo")
.foregroundColor(darkMode ? .white : .black)
}
}
.frame(width: 44, height: 44)
.onTapGesture {
showPhotoLibrary.toggle()
}
.sheet(isPresented: $showPhotoLibrary) {
ImagePicker(sourceType: .photoLibrary, selectedImage: self.$image)
}
The ImagePicker:
import SwiftUI
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
#Binding var selectedImage: UIImage
#Environment(\.presentationMode) private var presentationMode
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let imagePicker = UIImagePickerController()
imagePicker.sourceType = sourceType
imagePicker.delegate = context.coordinator
return imagePicker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
final class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var parent: ImagePicker
init(_ parent: ImagePicker) {
self.parent = parent
}
internal func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
parent.selectedImage = image
}
parent.presentationMode.wrappedValue.dismiss()
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
}
I've seen many struggle with this, it's all over the Apple dev forums so I thought I would have a go at solving it. From my own testing I believe the reason for the problems is UIImagePickerController is designed to be presented using the present method of a parent View Controller, not used as the root view controller of a SwiftUI presented sheet, as Apple (in their sample code) and everyone else seem to be doing. Below is my incomplete test code, which shows a working image picker where the search works and it can also be dragged down to dismiss, so I think this might be the correct solution.
The idea is we use UIViewControllerRepresentable to present our own custom view controller that presents or dismisses the image picker view controller when the present boolean changes.
struct ImagePickerTest: View {
#State var show = false
#State var image1: UIImage?
var body: some View {
VStack {
Button("Hello, World!") {
show.toggle()
}
Text("image: \(image1?.description ?? "" )")
}
.imagePicking(isPresented: $show, selectedImage: $image1)
}
}
extension View {
// this could be refactored into a `ViewModifier`
func imagePicking(isPresented: Binding<Bool>, selectedImage: Binding<UIImage?>) -> some View {
ZStack {
ImagePicking(isPresented: isPresented, selectedImage: selectedImage)
self
}
}
}
class MyViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
var dismissPicker: (() -> Void)?
var selectImage: ((UIImage) -> Void)?
func showPickerIfNecessary() {
if self.presentedViewController != nil {
return
}
let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .photoLibrary
imagePickerController.delegate = self
present(imagePickerController, animated: true)
}
func hidePickerIfNecessary() {
if let vc = self.presentedViewController {
vc.dismiss(animated: true)
}
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
print("imagePickerControllerDidCancel")
dismissPicker?()
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
print("didFinishPickingMediaWithInfo")
if let image = (info[.editedImage] ?? info[.originalImage]) as? UIImage {
selectImage?(image)
dismissPicker?()
}
}
}
struct ImagePicking: UIViewControllerRepresentable {
#Binding var isPresented: Bool
#Binding var selectedImage: UIImage?
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
uiViewController.dismissPicker = {
isPresented = false
}
uiViewController.selectImage = { image in
selectedImage = image
}
if isPresented {
uiViewController.showPickerIfNecessary()
} else {
uiViewController.hidePickerIfNecessary()
}
}
func makeUIViewController(context: Context) -> some MyViewController {
MyViewController()
}
}
Before I started, I verified the OP's code was failing when typing a search, it crashed with this error:
2022-08-31 22:39:17.808899+0100 Test[66967:5425868] [UI] -[PUPhotoPickerHostViewController viewServiceDidTerminateWithError:] Error Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "(null)" UserInfo={Message=Service Connection Interrupted}

Add a different modifier to each Action Sheet button

This is probably quite a simple question, but I can't find an answer.
I'm trying to build an ActionSheet with two buttons (as well as a cancel button):
Button "Select from Gallery" opens an imagePicker with sourceType set to .photoLibrary.
Button "Take a new picture" opens an imagePicker with sourceType set to .camera.
I've made the ActionSheet and the imagePicker successfully, but can't work out where to add the modifier to tell which sourceType should be used to each button. I managed to add it outside of the ActionSheet in a sheet() modifier in a normal button like this and everything worked well:
Button(action: {
self.show.toggle()
})
{Text("Take a new picture")}
.sheet(isPresented: self.$show, content: {
ImagePicker(sourceType: .camera, show: self.$show, image: self.$imageTemp)
})
However I can't see where to include this information in the ActionSheet. Many thanks to anyone who can help, I hope this is clear :-)
Here is my code:
struct ContentView: View {
#State private var showingActionSheet = false
#State var imageTemp : Data = (UIImage(systemName: "photo.on.rectangle.angled")?.jpegData(compressionQuality: 1))!
var body: some View {
NavigationView {
Image(uiImage: UIImage(data: imageTemp)!)
.onTapGesture {
self.showingActionSheet = true
}
.actionSheet(isPresented: $showingActionSheet) {
ActionSheet(title: Text("Image selector"), message: Text("Select an image"), buttons: [
.default(Text("Select from Gallery"))
{
self.show.toggle()
},
.default(Text("Take new picture")) {
self.show.toggle()
},
.cancel()
]
)
}
}
}
}
And, just in case, here is the code for my imagePicker, although I think it's probably not necessary.
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
#Binding var show: Bool
#Binding var image: Data
func makeCoordinator() -> ImagePicker.Coordinator {
let imagePicker = UIImagePickerController()
return ImagePicker.Coordinator(child1: self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
picker.sourceType = sourceType
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var child : ImagePicker
init(child1: ImagePicker) {
child = child1
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.child.show.toggle()
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let image = info[.originalImage]as! UIImage
let data = image.jpegData(compressionQuality: 0.45)
self.child.image = data!
self.child.show.toggle()
}
}
}
Your question pretty much boils down to "How can I present multiple sheets?", so this thread might be helpful.
Define a new enum to contain possible sheet types (gallery/take photo)
Declare a #State property to hold the current sheet type. It's optional because when it's nil, there will be no sheet presented.
Set the property to the type that you want
Use sheet(item:onDismiss:content:) instead of sheet(isPresented:onDismiss:content:). isPresented is best for static sheets. item is for when you have multiple sheet types, which is what you want.
enum PhotoSheetType: Identifiable { /// 1.
var id: UUID {
UUID()
}
case gallery
case picture
}
struct ContentView: View {
/// 2.
#State private var showingType: PhotoSheetType?
#State private var showingActionSheet = false
#State var imageTemp : Data = (UIImage(systemName: "photo.on.rectangle.angled")?.jpegData(compressionQuality: 1))!
var body: some View {
NavigationView {
Image(uiImage: UIImage(data: imageTemp)!)
.onTapGesture {
self.showingActionSheet = true
}
.actionSheet(isPresented: $showingActionSheet) {
ActionSheet(
title: Text("Image selector"),
message: Text("Select an image"),
buttons: [
.default(Text("Select from Gallery")) {
showingType = .gallery /// 3.
},
.default(Text("Take new picture")) {
showingType = .picture /// 3.
},
.cancel()
]
)
} /// 4.
.sheet(item: $showingType) { type in
if type == .gallery {
ImagePicker(sourceType: .photoLibrary, showingType: $showingType, image: self.$imageTemp)
} else {
ImagePicker(sourceType: .camera, showingType: $showingType, image: self.$imageTemp)
}
}
}
}
}
You'll also need to modify your ImagePicker so that the Binding takes in a PhotoSheetType? instead of Bool. To dismiss the sheet, just set showingType to nil.
struct ImagePicker: UIViewControllerRepresentable {
var sourceType: UIImagePickerController.SourceType = .photoLibrary
#Binding var showingType: PhotoSheetType?
#Binding var image: Data
func makeCoordinator() -> ImagePicker.Coordinator {
let imagePicker = UIImagePickerController()
return ImagePicker.Coordinator(child1: self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ImagePicker>) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.delegate = context.coordinator
picker.sourceType = sourceType
return picker
}
func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<ImagePicker>) {
}
class Coordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate {
var child : ImagePicker
init(child1: ImagePicker) {
child = child1
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
self.child.showingType = nil /// set to nil here
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
let image = info[.originalImage] as! UIImage
let data = image.jpegData(compressionQuality: 0.45)
self.child.image = data!
self.child.showingType = nil /// set to nil here
}
}
}

SwiftUI: How Can I Present A View Over All Views? (Especially Sheets)

I want to show Image Viewer over all views when users tap into an image. It's working well without sheets but if there is a sheet on view, the image viewer stays behind it. How can I show image viewer over sheets too? I researched too much but I could not find any solution yet.
ContentView:
#ObservedObject var authVM: AuthVM = .shared
var body: some View {
ZStack{
TabView(selection: self.$authVM.selectedTab) {
HomeTab()
.tabItem {
Image(systemName: "house.fill")
.renderingMode(.template)
Text("Home")
}.tag(SelectedTab.home)
// Other tabs...
}
if self.authVM.showImageViewer{
PhotoViewer(viewerImages: $authVM.images, currentPageIndex: $authVM.imageIndex)
.edgesIgnoringSafeArea(.vertical)
}
}
}
I'm using SKPhotoBrowser pod (UIKit) with UIViewControllerRepresentable, maybe we can do something in UIKit to solve it?
import SwiftUI
import SKPhotoBrowser
struct PhotoViewer: UIViewControllerRepresentable {
#ObservedObject var authVM: AuthVM = .shared
#Binding var viewerImages:[SKPhoto]
#Binding var currentPageIndex: Int
func makeUIViewController(context: Context) -> SKPhotoBrowser {
SKPhotoBrowserOptions.displayHorizontalScrollIndicator = false
let browser = SKPhotoBrowser(photos: viewerImages)
browser.initializePageIndex(currentPageIndex)
browser.delegate = context.coordinator
return browser
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func updateUIViewController(_ browser: SKPhotoBrowser, context: Context) {
browser.photos = viewerImages
browser.currentPageIndex = currentPageIndex
}
class Coordinator: NSObject, SKPhotoBrowserDelegate {
var control: PhotoViewer
init(_ control: PhotoViewer) {
self.control = control
}
func didShowPhotoAtIndex(_ browser: PhotoViewer) {
self.control.currentPageIndex = browser.currentPageIndex
}
func didDismissAtPageIndex(_ index: Int) {
self.control.authVM.showImageViewer = false
}
}
}

How to dismiss PKToolPicker when view disappears in SwiftUI?

I'm trying to wrap PKCanvasView as a SwiftUI view called CanvasView. I'd like to be able to toggle the whole canvas on top of another view. When the CanvasView appears, I'd like the PKToolPicker to appear. When it disappears, I'd like the PKToolPicker to disappear.
I've found a few similar approaches on here but they only involve showing the picker or toggling the picker with a button; I'd like the picker visibility to be tied to the view visibility.
In the below example you can see that you can toggle the canvas, but once the tool picker is visible, it stays visible.
Here's my CanvasView:
import SwiftUI
import PencilKit
struct CanvasView: UIViewRepresentable {
class Coordinator: NSObject, PKCanvasViewDelegate {
var canvasView: Binding<PKCanvasView>
let onChange: () -> Void
init(canvasView: Binding<PKCanvasView>, onChange: #escaping () -> Void) {
self.canvasView = canvasView
self.onChange = onChange
}
func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
if canvasView.drawing.bounds.isEmpty == false {
onChange()
}
}
}
#Binding var canvasView: PKCanvasView
#Binding var toolPickerIsActive: Bool
private let toolPicker = PKToolPicker()
let onChange: () -> Void
func makeUIView(context: Context) -> PKCanvasView {
canvasView.backgroundColor = .clear
canvasView.isOpaque = true
canvasView.delegate = context.coordinator
showToolPicker()
return canvasView
}
func updateUIView(_ uiView: PKCanvasView, context: Context) {
toolPicker.setVisible(toolPickerIsActive, forFirstResponder: uiView)
}
func showToolPicker() {
toolPicker.setVisible(true, forFirstResponder: canvasView)
toolPicker.addObserver(canvasView)
canvasView.becomeFirstResponder()
}
func makeCoordinator() -> Coordinator {
Coordinator(canvasView: $canvasView, onChange: onChange)
}
}
And an example ContentView:
struct ContentView: View {
#State private var canvasView = PKCanvasView()
#State private var toolPickerIsActive = false
#State private var canvasIsVisible = false
var body: some View {
ZStack {
if canvasIsVisible {
CanvasView(canvasView: $canvasView,
toolPickerIsActive: $toolPickerIsActive,
onChange: canvasDidChange)
.onAppear { toolPickerIsActive = true }
.onDisappear { toolPickerIsActive = false }
}
Button(action: {
canvasIsVisible.toggle()
}, label: {
Text("Toggle canvas view")
})
}
}
private func canvasDidChange() {
// Do something with updated canvas.
}
}
Any guidance would be much appreciated!
In your scenario the CanvasView is destroyed on disappear, so SwiftUI rendering engine just not update it on any state change (as it see that no needs for that).
The possible solution for this use-case is to hide picker on coordinator deinit (because it is destroyed with owner view).
Here is a demo. Tested with Xcode 12.4 / iOS 14.4
struct CanvasView: UIViewRepresentable {
class Coordinator: NSObject, PKCanvasViewDelegate {
var canvasView: Binding<PKCanvasView>
let onChange: () -> Void
private let toolPicker: PKToolPicker
deinit { // << here !!
toolPicker.setVisible(false, forFirstResponder: canvasView.wrappedValue)
toolPicker.removeObserver(canvasView.wrappedValue)
}
init(canvasView: Binding<PKCanvasView>, toolPicker: PKToolPicker, onChange: #escaping () -> Void) {
self.canvasView = canvasView
self.onChange = onChange
self.toolPicker = toolPicker
}
func canvasViewDrawingDidChange(_ canvasView: PKCanvasView) {
if canvasView.drawing.bounds.isEmpty == false {
onChange()
}
}
}
#Binding var canvasView: PKCanvasView
#Binding var toolPickerIsActive: Bool
private let toolPicker = PKToolPicker()
let onChange: () -> Void
func makeUIView(context: Context) -> PKCanvasView {
canvasView.backgroundColor = .clear
canvasView.isOpaque = true
canvasView.delegate = context.coordinator
showToolPicker()
return canvasView
}
func updateUIView(_ uiView: PKCanvasView, context: Context) {
toolPicker.setVisible(toolPickerIsActive, forFirstResponder: uiView)
}
func showToolPicker() {
toolPicker.setVisible(true, forFirstResponder: canvasView)
toolPicker.addObserver(canvasView)
canvasView.becomeFirstResponder()
}
func makeCoordinator() -> Coordinator {
Coordinator(canvasView: $canvasView, toolPicker: toolPicker, onChange: onChange)
}
}
struct ContentView: View {
#State private var canvasView = PKCanvasView()
#State private var toolPickerIsActive = false
#State private var canvasIsVisible = false
var body: some View {
ZStack {
if canvasIsVisible {
CanvasView(canvasView: $canvasView,
toolPickerIsActive: $toolPickerIsActive,
onChange: canvasDidChange)
.onAppear { toolPickerIsActive = true }
// .onDisappear { toolPickerIsActive = false }
}
Button(action: {
canvasIsVisible.toggle()
}, label: {
Text("Toggle canvas view")
})
}
}
private func canvasDidChange() {
// Do something with updated canvas.
}
}
Note: there might be redesign of ownership, so toolPicker will live only within coordinator, but it does not change idea, and is up to you.

SwiftUI - CNContactViewController NavigationBar problem

I am trying to implement CNContactViewDelegate to be able to show detail of the CNContact. And apparently, I am the first one to implement it with SwiftUI and getting problems. Anyway, I can see the detail of CNContact with using UIViewControllerRepresentable but I have an issue with the NavigationBar, which there is gap between the Contact's image and StatusBar -because of the NavigationBar and NavigationLink I think- and this gap is not there in the native Contacts app and apparently in this link that implemented the framework in UIKit.
Here is the code;
struct ContactsListView: View {
#ObservedObject var contactsModel: ContactsViewModel
var body: some View {
NavigationView{
List {
//After some ForEach's and Section's
//This view is working.
NavigationLink(destination: ContactDetailView(contact: self.$contactsModel.contacts[sectionIdx].contacts[contactIdx])) {
Text(self.contactsModel.contacts[sectionIdx].contacts[contactIdx].givenName)
}
}
.navigationBarTitle("Contacts")
}
}
}
struct ContactView: UIViewControllerRepresentable {
#Binding var contact: CNContact
func makeCoordinator() -> ContactView.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ContactView>) -> CNContactViewController {
let controller = CNContactViewController(for: contact)
self.navigationBarHidden(true)
return controller
}
func updateUIViewController(_ uiViewController: CNContactViewController, context: UIViewControllerRepresentableContext<ContactView>) {
print(context)
}
class Coordinator: NSObject, CNContactViewControllerDelegate {
var parent: ContactView
init(_ contactDetail: ContactView) {
self.parent = contactDetail
self.parent.navigationBarHidden(true)
}
}
}
In the ContactView, both of those self.navigationBarHidden(true)'s are not working. As an example of the problem here is the native app's screenshot;
And here is the result of my code;
Posted my comment on the solution and then I came to the idea to wrap the contact view controller inside my custom NavigationController. And voila that fixed it!
struct ContactView: UIViewControllerRepresentable {
var contact: CNContact
func makeCoordinator() -> ContactView.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ContactView>) -> NavigationController {
let controller = CNContactViewController(forUnknownContact: contact)
controller.contactStore = CNContactStore()
controller.delegate = context.coordinator
let navigationController = NavigationController(rootViewController: controller)
return navigationController
}
func updateUIViewController(_ uiViewController: NavigationController, context: UIViewControllerRepresentableContext<ContactView>) {
}
class Coordinator: NSObject, CNContactViewControllerDelegate {
var parent: ContactView
init(_ contactDetail: ContactView) {
self.parent = contactDetail
}
func contactViewController(_ viewController: CNContactViewController,
didCompleteWith contact: CNContact?) {
}
func contactViewController(_ viewController: CNContactViewController,
shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
return true
}
}
}
As the question is got an upvote I thought I can share my half way solution. This solves the gap however during the transition to detail there is a glitch of navigation bar with background color. After the transition it is becoming clear.
struct ContactDetailView: View {
var contact: CNContact
var body: some View {
ZStack {
Color.clear
ContactView(contact: self.contact)
.navigationBarTitle("", displayMode: .inline)
}.edgesIgnoringSafeArea(.top)
}
}
struct ContactView: UIViewControllerRepresentable {
var contact: CNContact
func makeCoordinator() -> ContactView.Coordinator {
Coordinator(self)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ContactView>) -> CNContactViewController {
let controller = CNContactViewController(forUnknownContact: contact)
controller.allowsActions = true
controller.allowsEditing = false
controller.delegate = context.coordinator
return controller
}
func updateUIViewController(_ uiViewController: CNContactViewController, context: UIViewControllerRepresentableContext<ContactView>) {
print("updated")
}
class Coordinator: NSObject, CNContactViewControllerDelegate {
var parent: ContactView
init(_ contactDetail: ContactView) {
self.parent = contactDetail
}
func contactViewController(_ viewController: CNContactViewController, didCompleteWith contact: CNContact?) {
}
func contactViewController(_ viewController: CNContactViewController, shouldPerformDefaultActionFor property: CNContactProperty) -> Bool {
return true
}
}
}