好,
所以这可能是微不足道的,但我不确定如何解决。
我有一个在SwiftUI视图调用时创建的UIViewController:
func makeUIViewController(context: Context) -> MyViewController
Run Code Online (Sandbox Code Playgroud)
像我们在教程中看到的那样,进行该调用的View在SceneDelegate中获得了一个环境对象:
window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(MyData()))
Run Code Online (Sandbox Code Playgroud)
我想做的是在UIViewController逻辑中使用该环境对象(MyData())。ViewController会根据需要在MyData的实例上进行读/写操作,据我了解,由于MyData符合BindableObject,因此应该导致SwiftUI视图做出相应的反应。
因此,在makeUIViewController调用中,我得到了UIViewControllerRepresentableContext。我可以在上下文中看到环境:
context.environment
Run Code Online (Sandbox Code Playgroud)
如果在调试期间在控制台中将其打印,则会看到以下内容:
context.environment: [EnvironmentPropertyKey<PreferenceBridgeKey> = Value(value: Optional(SwiftUI.PreferenceBridge)), EnvironmentPropertyKey<FontKey> = Optional(SwiftUI.Font(provider: SwiftUI.(unknown context at $1c652cbec).FontBox<SwiftUI.Font.(unknown context at $1c656e2cc).TextStyleProvider>)), .......
Run Code Online (Sandbox Code Playgroud)
在打印中,我看到MyData environmentObject实例:
EnvironmentPropertyKey<StoreKey<MyData>> = Optional(MyApp.MyData), ...
Run Code Online (Sandbox Code Playgroud)
我不确定如何从context.environment中给我的环境值中获取MyData。
我试图找出如何为MyData获取正确的EnvironmentKey,以便尝试访问它的下标... context.environment [myKey ...]
如何从上下文给我的环境值中取回MyData?
现在可以使用 @EnvironmentObject(但在 Xcode 预览版中不行)。使用 Xcode 11.1/Swift 5.1。为了简单起见,它使用了 UIViewRepresentable,但同样适用于 UIViewControllerRepresentable,因为它也是 SwiftUI View
这是完整的演示

import SwiftUI
import Combine
import UIKit
class AppState: ObservableObject {
@Published var simpleFlag = false
}
struct CustomUIView: UIViewRepresentable {
typealias UIViewType = UIButton
@EnvironmentObject var settings: AppState
func makeUIView(context: Context) -> UIButton {
let button = UIButton(type: UIButton.ButtonType.roundedRect)
button.setTitle("Tap UIButton", for: .normal)
button.actionHandler(controlEvents: UIControl.Event.touchUpInside) {
self.settings.simpleFlag.toggle()
}
return button
}
func updateUIView(_ uiView: UIButton, context: UIViewRepresentableContext<CustomUIView>) {
}
}
struct ContentView: View {
@ObservedObject var settings: AppState = AppState()
var body: some View {
VStack(alignment: .center) {
Spacer()
CustomUIView()
.environmentObject(self.settings)
.frame(width: 100, height: 40)
.border(Color.blue)
Spacer()
if self.settings.simpleFlag {
Text("Activated").padding().background(Color.red)
}
Button(action: {
self.settings.simpleFlag.toggle()
}) {
Text("SwiftUI Button")
}
.padding()
.border(Color.blue)
}
.edgesIgnoringSafeArea(.all)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(AppState())
}
}
/// Just utility below
extension UIButton {
private func actionHandler(action:(() -> Void)? = nil) {
struct __ { static var action :(() -> Void)? }
if action != nil { __.action = action }
else { __.action?() }
}
@objc private func triggerActionHandler() {
self.actionHandler()
}
func actionHandler(controlEvents control :UIControl.Event, for action:@escaping () -> Void) {
self.actionHandler(action: action)
self.addTarget(self, action: #selector(triggerActionHandler), for: control)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
461 次 |
| 最近记录: |