我使用这种方法将相机与swiftUI合并: https://medium.com/@gaspard.rosay/create-a-camera-app-with-swiftui-60876fcb9118
UIViewControllerRepresentable由PageFourView类实现。 PageFourView是父级视图的TabView之一。我有一个@EnvironmentObject
从SceneDelegate传递到父视图,然后传递给PageFourView。但是,当我尝试从PageFourView的makeUIViewController方法访问@EnvironmentObject
时,出现错误:
严重错误:找不到数据类型的ObservableObject。一种 数据的View.environmentObject(_ :)作为其祖先可能会丢失 此视图
...即使我可以从context.environment中看到@Environment对象。这是我的代码:
import UIKit
import SwiftUI
import Combine
final class PageFourView: UIViewController, UIViewControllerRepresentable {
public typealias UIViewControllerType = PageFourView
@EnvironmentObject var data: Data
var previewView: UIView!
override func viewDidLoad() {
previewView = UIView(frame: CGRect(x:0, y:0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
previewView.contentMode = UIView.ContentMode.scaleAspectFit
view.addSubview(previewView)
}
func makeUIViewController(context: UIViewControllerRepresentableContext<PageFourView>) -> PageFourView {
print(context.environment)
print(self.data.Name)
return PageFourView()
}
func updateUIViewController(_ uiViewController: PageFourView, context: UIViewControllerRepresentableContext<PageFourView>) {
}
}
struct PageFourView_Previews: PreviewProvider {
@State static var data = Data()
static var previews: some View {
PageFourView().environmentObject(self.data)
}
}
这是从中调用PageFourView的父母视图:
import SwiftUI
struct AppView: View {
@EnvironmentObject var data: Data
var body: some View {
TabView {
PageOneView().environmentObject(data)
.tabItem {
Text("PageOne")
}
PageTwoView().environmentObject(data)
.tabItem {
Text("PageTwo")
}
PageThreeView().environmentObject(data)
.tabItem {
Text("PageThree")
}
PageFourView().environmentObject(data)
.tabItem {
Text("PageFour")
}
}
}
}
struct AppView_Previews: PreviewProvider {
@State static var data = Data()
static var previews: some View {
AppView().environmentObject(self.data)
}
}
final class CameraViewController: UIViewController {
let cameraController = CameraController()
var previewView: UIView!
override func viewDidLoad() {
previewView = UIView(frame: CGRect(x:0, y:0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
previewView.contentMode = UIView.ContentMode.scaleAspectFit
view.addSubview(previewView)
cameraController.prepare {(error) in
if let error = error {
print(error)
}
try? self.cameraController.displayPreview(on: self.previewView)
}
}
}
extension CameraViewController : UIViewControllerRepresentable{
public typealias UIViewControllerType = CameraViewController
public func makeUIViewController(context: UIViewControllerRepresentableContext<CameraViewController>) -> CameraViewController {
return CameraViewController()
}
public func updateUIViewController(_ uiViewController: CameraViewController, context: UIViewControllerRepresentableContext<CameraViewController>) {
}
}
答案 0 :(得分:1)
UIViewRepresentable
和UIViewControllerRepresentable
是-View
和必须是结构。
在上述情况下,不需要控制器可表示,因为您使用视图进行操作,因此此处为已更正的代码:
struct PageFourView: UIViewRepresentable {
@EnvironmentObject var data: Data
func makeUIView(context: Context) -> UIView {
let view = UIView(frame: CGRect(x:0, y:0, width: UIScreen.main.bounds.size.width,
height: UIScreen.main.bounds.size.height))
view.contentMode = UIView.ContentMode.scaleAspectFit
print(context.environment)
print(self.data.Name)
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
}
}
顺便说一句,您无需将.environmentObject
传递给相同视图层次结构中的子视图,仅需要将新层次结构(如图纸)传递给子视图,因此您可以使用以下简化代码
var body: some View {
TabView {
PageOneView()
.tabItem {
Text("PageOne")
}
PageTwoView()
.tabItem {
Text("PageTwo")
}
PageThreeView()
.tabItem {
Text("PageThree")
}
PageFourView()
.tabItem {
Text("PageFour")
}
}
}
更新:CameraViewController
只需如下包装
struct CameraView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> CameraViewController {
CameraViewController()
}
func updateUIViewController(_ uiViewController: CameraViewController, context: Context) {
}
}