如何通过SwiftUI Button在UIViewController中执行函数?

2uluyalo  于 12个月前  发布在  Swift
关注(0)|答案(2)|浏览(88)

在下面的代码中,我试图弄清楚如何使用SwiftUI按钮执行savePhoto函数。这实际上是我试图解决的问题的简化版本,但仍然无法解决这个问题。我在ContentView中创建的按钮是我想象如何解决这个问题的,但由于SwiftUI结构,我好像找不到别的办法。
这里是我的SwiftUI视图:

struct ContentView: View {
    var body: some View {
        ZStack{
            AnotherControllerView()
            Button(action: { AnotherControllerView.savePhoto() }){
                Text("Save Photo")
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

字符串

和我集成的UIViewController:

import Foundation
import SwiftUI
import UIKit

struct AnotherControllerView : UIViewControllerRepresentable {

    typealias UIViewControllerType = AnotherController

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

    func makeUIViewController(context: UIViewControllerRepresentableContext<AnotherControllerView>) -> AnotherController {

        return AnotherController()
    }

    func updateUIViewController(_ uiViewController: AnotherController, context: UIViewControllerRepresentableContext<AnotherControllerView>) {

    }

    class Coordinator : NSObject {
        var parent : AnotherControllerView
        init(_ viewController : AnotherControllerView){
            self.parent = viewController
        }
    }
}

class AnotherController : UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.blue
    }

    func savePhoto(){

        let alert = UIAlertController(title: "Save Photo to Camera Roll", message: "Would you like to save your drawing to the camera roll?", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: nil))
        alert.addAction(UIAlertAction(title: "Save", style: .default, handler: someHandler))
        self.present(alert, animated: true)
    }

    func someHandler(alert: UIAlertAction!) {
        print("Handler executed")
    }
}

cygmwpex

cygmwpex1#

你好,为了控制UIViewController,我们需要在View和UIViewControllerRepresentable之间创建一个绑定,让我们在代码中解释一下:首先,你需要在AnotherControllerView中声明一个新的带有@Binding注解的变量。
会是这样的:

struct AnotherControllerView : UIViewControllerRepresentable {

    @Binding var isShown: Bool
    typealias UIViewControllerType = AnotherController

    func makeCoordinator() -> AnotherControllerView.Coordinator {
        Coordinator()
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<AnotherControllerView>) -> AnotherController {

        return AnotherController(isShown: $isShown)
    }

    func updateUIViewController(_ controller: AnotherController, context: UIViewControllerRepresentableContext<AnotherControllerView>) {
        if(self.isShown){
            controller.savePhoto()
        }
    }

    class Coordinator : NSObject {

    }
}

字符串
因此,在updateUIViewController中,我们在那里实现逻辑

class AnotherController : UIViewController {

     @Binding var isShown: Bool

    init(isShown: Binding<Bool>) {
        _isShown = isShown
        super.init(nibName: nil, bundle: nil)

    }


    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.blue
    }

    func savePhoto(){

        let alert = UIAlertController(title: "Save Photo to Camera Roll", message: "Would you like to save your drawing to the camera roll?", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Cancel", style: .default, handler: cancelAlert))
        alert.addAction(UIAlertAction(title: "Save", style: .default, handler: someHandler))
        self.present(alert, animated: true)
    }

    func cancelAlert(alert: UIAlertAction!) {
        self.isShown = false
    }

    func someHandler(alert: UIAlertAction!) {
        print("Handler executed")
    }
}


如果你想捕捉一个图像,让我来展示一下我是如何实现的:

struct CaptureImageView {
    @Binding var isShown: Bool
    @Binding var image: Image?
    var sourceType: UIImagePickerController.SourceType

    func makeCoordinator() -> Coordinator {
        return Coordinator(isShown: $isShown, image: $image)
    }
}

extension CaptureImageView: UIViewControllerRepresentable {
    func makeUIViewController(context: UIViewControllerRepresentableContext<CaptureImageView>) -> UIImagePickerController {
        let picker = UIImagePickerController()
        picker.delegate = context.coordinator
        picker.sourceType = sourceType
        return picker
    }

    func updateUIViewController(_ uiViewController: UIImagePickerController, context: UIViewControllerRepresentableContext<CaptureImageView>) {

    }

    class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
        @Binding var isCoordindatorShown: Bool
        @Binding var imageInCoordinator: Image?

        init(isShown: Binding<Bool>, image: Binding<Image?>) {
            _isCoordindatorShown = isShown
            _imageInCoordinator = image
        }

        func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
            guard let unwrapImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {return}
            imageInCoordinator = Image(uiImage: unwrapImage)
            isCoordindatorShown = false
        }

        func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
            isCoordindatorShown = false
        }
    }

}


在身体里我叫它:

CaptureImageView(isShown: $showCaptureImageView, image: $imageCaptured, sourceType: importSourceType)

ecbunoof

ecbunoof2#

如果AnotherControllerView很大,而您在新中很少使用它,则可以考虑使用更简单的解决方法。

struct ContentAnotherControllerView: View {
                
    let anotherControllerView = AnotherControllerView()
                
    var body: some View {
        ZStack {
            anotherControllerView
            Button(action: { anotherControllerView.savePhoto() }) {
                Text("Save Photo")
            }
        }
    }
}


struct AnotherControllerView : UIViewControllerRepresentable {

    typealias UIViewControllerType = AnotherController
    var savePhotoDelegate: AnotherController? = AnotherController()
    
    func savePhoto(){
        savePhotoDelegate?.savePhoto()
    }
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<AnotherControllerView>) -> AnotherController {
        if let savePhotoDelegate = savePhotoDelegate {
            return savePhotoDelegate
        }
        return AnotherController()
    }
}

字符串
这种方法只是提醒我们在某些情况下可以重用一个视图。由于UIView桥不是纯SwiftUI域,您可以尝试这种方法。

相关问题