Кнопка закрытия в модальном интерфейсе SwiftUI вызывается из UIKit - PullRequest
3 голосов
/ 16 июня 2020

У меня есть модальное представление SwiftUI, которое я вызываю из основного представления UIKit. Я хочу добавить кнопку отклонения в свое модальное представление. Насколько я могу судить, в UIKit нет переменных @State, поэтому я создаю отдельное представление SwiftUI для хранения моей переменной @State, но по какой-то причине оно не работает. Как мне это исправить?

Мой код внутри основного ViewController:

var hack = StateInUIKitHack()
hack.modalIsPresented = true
let vc = UIHostingController(rootView: MoodCardView(isPresented: hack.$modalIsPresented, entryIndex: entryIndex, note: moodEntries[entryIndex].note ?? ""))
self.present(vc, animated: true, completion: nil)

StateInUIKitHack struct:

struct stateInUIKitHack: View {
     @State var modalIsPresented = false

    var body: some View {
        Text("Hello, World!")
    }
} 

Внутри MoodCardView.swift У меня есть:

 @Binding var isPresented: Bool

И если я создаю свой модальный лист из другого представления SwiftUI, классическим способом он отклоняет ОК, но мне нужно создать его из представления UIKit.

1 Ответ

3 голосов
/ 16 июня 2020

Вот демонстрация возможного подхода. Протестировано с Xcode 11.4 / Playground

enter image description here

Полный код игровой площадки:

import UIKit
import SwiftUI
import PlaygroundSupport

class ViewModel {
    var closeAction: () -> Void = {}
}

struct ModalView: View {
    var vm: ViewModel

    var body: some View {
        VStack {
            Text("I'm SwfitUI")
            Button("CloseMe") {
                self.vm.closeAction()
            }
        }
    }
}

class MyViewController : UIViewController {

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let button = UIButton(type: .roundedRect)
        button.setTitle("ShowIt", for: .normal)
        button.addTarget(self, action: #selector(MyViewController.showModal(_:)), for: .touchDown)

        view.addSubview(button)

        button.translatesAutoresizingMaskIntoConstraints = false
        button.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        self.view = view
    }

    @objc func showModal(_ : Any?) {
        let bridge = ViewModel()
        let vc = UIHostingController(rootView: ModalView(vm: bridge))
        bridge.closeAction = { [weak vc] in
            vc?.dismiss(animated: true)
        }
        self.present(vc, animated: true, completion: nil)
    }
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()
...