如何解决UIViewControllerRepresentable 是否有理由永远不应该是一个类?
假设您并不真正需要 SwiftUI 功能。 IE。您的文件中没有 import SwiftUI
。相反,您只需要
import protocol SwiftUI.UIViewControllerRepresentable
一般来说,您将不得不涉及一个委托对象:充其量 an AnyObject
,通常,因为 UIKit API 很旧,NSObject
。
常见的模式是为此使用一个 Coordinator 类,并且让 View 本身是一个结构体,但是在那个间接性中总是存在点吗?
这是一个在实践中没有给我带来任何麻烦的例子:
import Combine
import MultipeerConnectivity
import protocol SwiftUI.UIViewControllerRepresentable
extension MCbrowserViewController {
final class View: NSObject {
init(
serviceType: String,session: MCSession,peerCountRange: ClosedRange<Int>? = nil
) {
self.serviceType = serviceType
self.session = session
self.peerCountRange = peerCountRange
}
private let serviceType: String
private uNowned let session: MCSession
private let peerCountRange: ClosedRange<Int>?
private let didFinishSubject = CompletionSubject()
private let wasCancelledSubject = CompletionSubject()
}
}
// MARK: - internal
extension MCbrowserViewController.View {
var didFinishPublisher: AnyPublisher<Void,Never> { didFinishSubject.erasetoAnyPublisher() }
var wasCancelledPublisher: AnyPublisher<Void,Never> { wasCancelledSubject.erasetoAnyPublisher() }
}
// MARK: - private
private extension MCbrowserViewController {
typealias CompletionSubject = PassthroughSubject<Void,Never>
}
// MARK: - UIViewControllerRepresentable
extension MCbrowserViewController.View: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MCbrowserViewController {
let browser = MCbrowserViewController(
serviceType: serviceType,session: session
)
browser.delegate = self
if let peerCountRange = peerCountRange {
browser.minimumNumberOfPeers = peerCountRange.lowerBound
browser.maximumNumberOfPeers = peerCountRange.upperBound
}
return browser
}
func updateUIViewController(_: MCbrowserViewController,context _: Context) { }
}
// MARK: - MCbrowserViewControllerDelegate
extension MCbrowserViewController.View: MCbrowserViewControllerDelegate {
func browserViewControllerDidFinish(_: MCbrowserViewController) {
didFinishSubject.send()
}
func browserViewControllerWasCancelled(_: MCbrowserViewController) {
wasCancelledSubject.send()
}
}
解决方法
对于您的问题,我没有完整详细的答案,但是您的解决方案存在一些问题。
在 SwiftUI 中,如果我们更新 View
,它会调用 init
重新创建 View
,然后调用 updateUIViewController
。
就您而言,每当您更新 View
时,不仅会重新创建您的视图,还会重新创建您的两个主题,因此在重新创建后附加到 Publisher
的任何内容都不会收到事件没有了。
也许这就是我们更喜欢使用 Coordinator
的原因。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。