问题描述
我使用这种方法将相机与 swiftUI 结合起来:https://medium.com/@gaspard.罗赛/创建-a-camera-app-with-swiftui-60876fcb9118
UIViewControllerRepresentable 由 PageFourView 类实现.PageFourView 是父视图的 TabView 之一.我有一个 @EnvironmentObject
从 SceneDelegate 传递到父视图,然后传递到 PageFourView.但是,当我尝试从 PageFourView 的 makeUIViewController 方法访问 @EnvironmentObject
时,出现错误:
致命错误:找不到数据类型的 ObservableObject.一种View.environmentObject(_:) for Data 可能缺少作为此视图
... 即使我可以从 context.environment 中看到 @Environment 对象.这是我的代码:
导入 UIKit导入 SwiftUI进口结合最终类 PageFourView: UIViewController, UIViewControllerRepresentable {公共类型别名 UIViewControllerType = PageFourView@EnvironmentObject var 数据:数据var previewView: UIView!覆盖 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.scaleAspectFitview.addSubview(previewView)}func makeUIViewController(context: UIViewControllerRepresentableContext) ->PageFourView {打印(上下文.环境)打印(self.data.Name)返回 PageFourView()}func updateUIViewController(_ uiViewController: PageFourView, context: UIViewControllerRepresentableContext) {}}struct PageFourView_Previews: PreviewProvider {@State 静态 var 数据 = Data()静态 var 预览:一些视图 {PageFourView().environmentObject(self.data)}}
这是调用 PageFourView 的父视图:
导入 SwiftUIstruct AppView:查看{@EnvironmentObject var 数据:数据var主体:一些视图{标签视图{PageOneView().environmentObject(data).tabItem {文本(PageOne")}PageTwoView().environmentObject(data).tabItem {文本(第二页")}PageThreeView().environmentObject(data).tabItem {文本(第三页")}PageFourView().environmentObject(data).tabItem {文本(第四页")}}}}struct AppView_Previews: PreviewProvider {@State 静态 var 数据 = Data()静态 var 预览:一些视图 {AppView().environmentObject(self.data)}}final class CameraViewController: UIViewController {让 cameraController = CameraController()var previewView: UIView!覆盖 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.scaleAspectFitview.addSubview(previewView)cameraController.prepare {(error) in如果让错误 = 错误 {打印(错误)}尝试?self.cameraController.displayPreview(on: self.previewView)}}}扩展 CameraViewController : UIViewControllerRepresentable{公共类型别名 UIViewControllerType = CameraViewControllerpublic func makeUIViewController(context: UIViewControllerRepresentableContext) ->相机视图控制器 {返回 CameraViewController()}public func updateUIViewController(_ uiViewController: CameraViewController, context: UIViewControllerRepresentableContext) {}}
And UIViewRepresentable
and UIViewControllerRepresentable
is-a View
and 必须是结构体.
在描述的情况下不需要控制器可表示,因为您使用视图操作,所以这里是更正的代码:
struct PageFourView: UIViewRepresentable {@EnvironmentObject var 数据:数据func makeUIView(context: Context) ->界面视图{让视图 = UIView(frame: CGRect(x:0, y:0, width: UIScreen.main.bounds.size.width,高度:UIScreen.main.bounds.size.height))view.contentMode = UIView.ContentMode.scaleAspectFit打印(上下文.环境)打印(self.data.Name)返回视图}func updateUIView(_ uiView: UIView, context: Context) {}}
顺便说一句,您不需要将 .environmentObject
传递给同一视图层次结构中的子视图,仅适用于新层次结构,例如工作表,因此您可以使用如下简化代码
var body: some View {标签视图{PageOneView().tabItem {文本(PageOne")}PageTwoView().tabItem {文本(第二页")}PageThreeView().tabItem {文本(第三页")}PageFourView().tabItem {文本(第四页")}}}
更新: CameraViewController
只需将其包装如下
struct CameraView: UIViewControllerRepresentable {func makeUIViewController(context: Context) ->相机视图控制器 {相机视图控制器()}func updateUIViewController(_ uiViewController: CameraViewController, context: Context) {}}
I used this approach to incorporate camera with swiftUI:https://medium.com/@gaspard.rosay/create-a-camera-app-with-swiftui-60876fcb9118
The UIViewControllerRepresentable is implemented by PageFourView class. PageFourView is one of the TabView of the parental View. I have an @EnvironmentObject
passed from the SceneDelegate to the parent view and then to PageFourView. But when I am trying to acess @EnvironmentObject
from makeUIViewController method of PageFourView I get an error:
... even though I can see the @Environment object from context.environment. Here is my code:
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)
}
}
here is the parental view that PageFourView is called from:
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>) {
}
}
And UIViewRepresentable
and UIViewControllerRepresentable
is-a View
and must be a struct.
In described case controller representable is not needed, because you operate with view, so here is corrected code:
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) {
}
}
btw, you don't need to pass .environmentObject
to subviews in same view hierarchy, only for new hierarchy, like sheets, so you can use simplified code as below
var body: some View {
TabView {
PageOneView()
.tabItem {
Text("PageOne")
}
PageTwoView()
.tabItem {
Text("PageTwo")
}
PageThreeView()
.tabItem {
Text("PageThree")
}
PageFourView()
.tabItem {
Text("PageFour")
}
}
}
Update: for CameraViewController
just wrap it as below
struct CameraView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> CameraViewController {
CameraViewController()
}
func updateUIViewController(_ uiViewController: CameraViewController, context: Context) {
}
}
这篇关于从 UIViewControllerRepresentable 对象访问 @Environment 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!