This is the 15th day of my participation in the August Text Challenge.More challenges in August

A, goals,

General layouts, such as list displays and menu bars, have been demonstrated several times in previous chapters. Without further ado, this section introduces some new and possible problems encountered during implementation.

SwiftUI has gone through two major releases since its release (3.0 will be released in September with a lot of new features, not to mention at this point), but there are still some components that are not supported enough, and some common components that are common in other UIs need to be implemented by themselves, and perhaps SwiftUI will be released in the future.

For example, one of the problems described in this section is the selection of pictures or taking pictures.

Second, inSwiftUIIn the callUIKitcomponent

The lack of native SwiftUI component support is bound to lead developers to adopt a mixed approach to development.

How do I use SwiftUI’s declarative programming syntax?

Use UIViewControllerRepresentable interface and implement it requires two makeUIViewController and updateUIViewController interface methods.

The makeUIViewController is used to create the corresponding component object and do some initialization. UpdateUIViewController is usually used to do some data updates based on context after the object is created.

For example, to create an Imagepicker. swift file, you need to do some basic transformation work before calling UIKit components in SwiftUI.

import SwiftUI

struct ImagePicker: UIViewControllerRepresentable {
    
    func makeUIViewController(context: Context) -> UIImagePickerController{}func updateUIViewController(_ uiViewController: UIImagePickerController.context: Context){}}Copy the code

With the above implementation

import SwiftUI

struct BrochureView: View {
    var body: some View {
        ImagePicker()}}Copy the code

ImagePicker can be used just like any other SwiftUI component.

Three,UIImagePickerControllercomponent

By using the UIImagePickerController component, you can invoke the phone’s photo album or camera function.

I’m going to create it first in the makeUIViewController.

let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .photoLibrary
return imagePickerController
Copy the code

SourceType specifies the source of the image selection. PhotoLibrary stands for photo album and camera stands for photo acquisition. This specifies how to get the album. In info.plist, specify access permissions and why. 1. The official review will be conducted when the APP is launched later; 2: When the user opens it for the first time, a permission popup window will pop up, and the user can access it only after asking for permission.

Four,ImagePickerIs recommended to call

It is recommended to use the sheet component +Button control mode to pop up the album page.

The code is as follows:


struct BoilingView: View {
    
    @State private var selectPhotoPresneted: Bool = false
    
    var body: some View {
        Button(action: {
            selectPhotoPresneted = true
        }, label: {
            Text("selected photo")
        }).sheet(isPresented: $selectPhotoPresneted, content: {
            ImagePicker()})}}Copy the code

Five, how to determine the choice of a good picture

All the above are foreshadowing, the ultimate purpose is to choose the picture for later use.

struct ImagePicker: UIViewControllerRepresentable {
    
    @Binding var image: UIImage
    
    func makeUIViewController(context: Context) -> UIImagePickerController {
        let imagePickerController = UIImagePickerController()
        imagePickerController.sourceType = .photoLibrary
        imagePickerController.delegate = context.coordinator
        return imagePickerController
    }
    
    func updateUIViewController(_ uiViewController: UIImagePickerController.context: Context){}func makeCoordinator(a) -> Coordinator {
        Coordinator(parent: self)}class Coordinator: NSObject.UINavigationControllerDelegate.UIImagePickerControllerDelegate {
        
        var parent: ImagePicker
        
        init(parent: ImagePicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController.didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                parent.image = image
            }
        }
        
    }
 
}
Copy the code

This is passed by @binding var Image: UIImage, which is sensed by the upper level caller after the user selects the image.

Rewrite makeCoordinator method, and through UIImagePickerControllerDelegate agreement after the user to select pictures, trigger imagePickerController method to perform the method, then select images assigned to image variables.

Finally, imagePickerController. Delegate = context. The coordinator into components.

Close the page and return to the home page

struct ImagePicker: UIViewControllerRepresentable {
    
    @Environment(\.presentationMode) var presentationMode
    
    .
    
    class Coordinator: NSObject.UINavigationControllerDelegate.UIImagePickerControllerDelegate {
        
        var parent: ImagePicker
        
        init(parent: ImagePicker) {
            self.parent = parent
        }
        
        func imagePickerController(_ picker: UIImagePickerController.didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
                parent.image = image
            }
            parent.presentationMode.wrappedValue.dismiss()
        }
        
    }
    
}
Copy the code