标签: environmentobject

如何访问类中的全局环境对象?

我有一个类需要更新全局环境对象。我可以整天在结构之间传递该环境对象,但是如何允许类对象访问同一变量?

import SwiftUI

class Global: ObservableObject
{
    @Published var num = 10
}

class MyClass:ObservableObject
{
    @Published var mode = 1
    @EnvironmentObject var global: Global

    func updateMode()
    {
        self.mode += 1
        global.num += 1
    }
}

@main
struct MyApp: App
{
    let settings = Global()
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(settings)
            }
    }
}

struct ContentView: View
{
    @EnvironmentObject var global: Global
    @ObservedObject var myClass = MyClass()
    
    var body: some View
    {
        VStack
        {
            Text("Setting \(global.num)")
            Text("Mode …
Run Code Online (Sandbox Code Playgroud)

swiftui environmentobject

11
推荐指数
1
解决办法
6103
查看次数

在 SwiftUI 中的非视图类之间传递环境对象

我知道EnvironmentObject属性包装器可用于将对象传递给视图。我有一个会话对象,我正在将其传递给我的视图。现在我需要将其传递到我的模型类之一(即非视图)。理想情况下,该模型(接收会话对象)被实例化为StateObject.

struct CreditDetailsView: View {
  @EnvironmentObject var session: Session
  @StateObject var transactionsModel = TransactionsModel(token: session.token)
Run Code Online (Sandbox Code Playgroud)

上面的代码将不起作用(可以理解),因为:

cannot use instance member 'session' within property initializer; property initializers run before 'self' is available
Run Code Online (Sandbox Code Playgroud)

关于如何将会话传递到 的任何建议TransactionsModel

swift swiftui environmentobject

10
推荐指数
1
解决办法
3380
查看次数

SwiftUI 在presentationMode?.wrappedValue.dismiss() 上随机崩溃

这就是崩溃的样子

在此处输入图片说明

所以它在 UIKit 线上随机崩溃

UIKitCore
-[UIViewController _ancestorViewControllerOfClass:allowModalParent:] + 44
Run Code Online (Sandbox Code Playgroud)

我在默认的 SwiftUI 导航堆栈中有视图:

struct MyView: View {
  @EnvironmentObject var viewModel: MyViewModel
  @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

var body: some View {
    ZStack {
      ......
    }
    .onAppear {
      self.viewModel
        .onViewAppear(presentationMode: self.presentationMode)
    }
  }
}

final class MyViewModel {
  var presentationMode: Binding<PresentationMode>?

  func onViewAppear(presentationMode: Binding<PresentationMode>) {
    self.presentationMode = presentationMode
  }

  func hide() {
    presentationMode?.wrappedValue.dismiss() // crashes after calling this
  }
}
Run Code Online (Sandbox Code Playgroud)

所以我以这种方式将 MyView 推送到导航堆栈中:

NavigationLink(
      destination: MyView()
    ) {
      Image(systemName: "plus.circle")
        .font(.title)
    }
Run Code Online (Sandbox Code Playgroud)

然后在用户在几秒钟后按下 …

presentation-model uinavigationcontroller swift swiftui environmentobject

9
推荐指数
1
解决办法
424
查看次数

SwiftUI 阻止 onReceive 在加载时触发

当我尝试接收的变量是 @EnvironmentObject 的 @Published 属性时,有什么方法可以阻止 onReceive 在视图最初加载时触发?

这是视图:

struct ContentView: View {
    @EnvironmentObject var appState: AppState
    
    var body: some View {
        VStack {
            Text(appState.test)
                .padding()
        }
        .onAppear() {
            appState.test = "World"
        }
        .onReceive(appState.$test) { test in
            print("Hello from onReceive: \(test)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是环境对象:

public class AppState: ObservableObject {
    @Published public var test = "hello"
}
Run Code Online (Sandbox Code Playgroud)

并输出:

Hello from onReceive: hello
Hello from onReceive: World
Run Code Online (Sandbox Code Playgroud)

我猜第一个是在注入环境对象时触发的。有什么方法可以防止这种情况(除了我在 onAppear 中设置的一些 hackish bool 之外)?理想情况下,我只想看到“Hello from onReceive: World”这只是一个简单的例子。在我的实际应用程序中,我正在从 onAppear 中的服务获取数据,在我的环境对象中,我有一个错误状态,当清除该错误状态时,我希望它触发 onReceive 执行一些其他逻辑,然后重新获取。

swift environmentobject

9
推荐指数
1
解决办法
2087
查看次数

@EnvironmentObject 和 @ObservedObject 有什么区别?

我一直在阅读 SwiftUI 中的属性包装器,我看到它们做得很好,但我真正不明白的一件事是@EnvironmentObject@ObservedObject之间的区别。

从我到目前为止所学到的,我看到@EnvironmentObject在我们的应用程序的各个地方都需要一个对象时使用,但我们不需要通过所有这些地方传递它。例如,如果我们有层次结构 A -> B -> C -> D 并且对象是在 A 处创建的,那么它会保存在环境中,以便我们可以将它直接从 A 传递到 D,如果 D 需要的话。

如果我们使用在 A 创建并需要传递给 D 的@ObservedObject,那么我们也需要通过 B 和 C。

但我仍然不知道如何决定使用哪一个。以下是我制作的 2 个示例项目:

struct ContentView2: View {
 
   var order = Order2()

   var body: some View {
      VStack {
           EditView2()
           DisplayView2()
       }
       .environmentObject(order)
   }
}
struct EditView2: View {
   @EnvironmentObject var user: Order2
 
   var body: some View {
       HStack{
       TextField("Fruit", text: $user.item)
       }
   }
}
struct …
Run Code Online (Sandbox Code Playgroud)

swiftui property-wrapper observedobject environmentobject

6
推荐指数
1
解决办法
1510
查看次数

SwiftUI:@Environment(\.presentationMode) 的解雇在 iOS14 中不起作用

我有一个视图,显示用于过滤列表中项目的工作表。该视图有这个变量:

struct JobsTab: View {

@State private var jobFilter: JobFilter = JobFilter()

var filter: some View {
        Button {
            self.showFilter = true
        } label: {
            Image(systemName: "line.horizontal.3.decrease.circle")
                .renderingMode(.original)
        }
        .sheet(isPresented: $showFilter) {
            FilterView($jobFilter, categoriesViewModel, jobsViewModel)
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是,在工作表中,我正在尝试以下操作,但单击“完成”按钮时无法关闭视图,只能单击“取消”按钮:

struct FilterView: View {
@Environment(\.presentationMode) var presentationMode
    @ObservedObject var categoriesViewModel: CategoriesViewModel
    @ObservedObject var jobsViewModel: JobsViewModel
    let filterViewModel: FilterViewModel
    
    @Binding var jobFilter: JobFilter
    
    @State private var draft: JobFilter
    @State var searchText = ""
init(_ jobFilter: Binding<JobFilter>, _ categoriesViewModel: CategoriesViewModel, _ jobsViewModel: JobsViewModel) { …
Run Code Online (Sandbox Code Playgroud)

swift swiftui environmentobject

6
推荐指数
1
解决办法
8909
查看次数

如何检查@EnvironmentObject是否已设置?(斯威夫特用户界面)

我拥有的:View 和 ViewModel(作为 View 结构的扩展)。
它们都使用AppState类型的@EnvironmentObject。
问题是我的预览由于以下错误而崩溃:
Fatal error: No ObservableObject of type AppState found
注释掉loadUserfunc 中的行可以避免崩溃。

struct ProfileView: View {
    @EnvironmentObject var appState: AppState
    @ObservedObject var viewModel = ViewModel()
    ...
}
Run Code Online (Sandbox Code Playgroud)
extension ProfileView {
    class ViewModel: ObservableObject {
        @EnvironmentObject var appState: AppState
        @Published var userVM = UserVM(.example)

        init() {
            loadUser()
        }

        func loadUser() {
            User.WebService.getSelf { user, errorMsg in
                DispatchQueue.main.async {
                    guard let user = user else {
                        /*self.appState.showingAlert = true
                        self.appState.alert = Alert(
                            title: Text("An …
Run Code Online (Sandbox Code Playgroud)

crash preview swiftui environmentobject

5
推荐指数
0
解决办法
520
查看次数

SwiftUI 如何将全局变量传递给非 View 类

我了解如何使用 @EnvironmentObject 使全局数据可用于任何视图类,但我找不到将变量传递给非视图类的方法。

我的情况似乎是一个常见问题,是:

  1. 登录,返回访问令牌。后续所有 api 调用都需要使用该 token
  2. 将访问令牌存储在 UserSettings 类中
  3. 将 UserSettings 放入环境存储桶中
    let contentView = ContentView()
        .environmentObject(UserSettings())
Run Code Online (Sandbox Code Playgroud)
  1. 每个视图将根据 api 调用返回的数据显示数据
struct HomeView: View {
    @EnvironmentObject var user: UserSettings  <=== ACCESS TO GLOBAL DATA
    @ObservedObject var categories = Categories()  <=== GET DATA FOR THIS VIEW

    var body: some View {
    ...
}
Run Code Online (Sandbox Code Playgroud)
  1. Categories() 是一个非视图 Swift 类,它将检索数据,但需要存储在 UserSettings 中的访问令牌
class Categories : ObservableObject {
    @Published var allCategories = CategoriesModel()
    @EnvironmentObject var user: UserSettings  <==== CANNOT ACCESS THIS DATA!

    init() { …
Run Code Online (Sandbox Code Playgroud)

swiftui observedobject environmentobject

4
推荐指数
1
解决办法
1689
查看次数

@EnvironmentObject 的 Swift 预览问题

在我的 Swift 项目中使用时,我无法获得更新的预览@EnvironmentObject。在模拟器中它工作正常,但预览却不行。它显示的错误如下:

ASET - Audio System Engineer Tools crashed due to missing environment of type: UserSettings. To resolve this add `.environmentObject(UserSettings(...))` to the appropriate preview.
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试添加它时,它仍然出现同样的问题。有人有一些有用的建议或解决方案吗?

preview swift environmentobject

4
推荐指数
2
解决办法
4924
查看次数

SwiftUI:在 Xcode 12/iOS 14 中使用环境对象(--&gt; 如何/在环境中放置对象?)

在编写我的第一个 iOS 应用程序的过程中,我遇到了一个新问题,到目前为止我无法找到解决方案:我想使用环境对象将信息传递到各种视图。

我知道对此有很多解释和教程(例如,在 hackingwithswift.com 上:https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-environmentobject-to-share-data- Between-意见

然而,所有这些教程似乎都在使用“场景委托”,根据我目前的理解,Xcode 12 中不存在这种委托。

因此,我正在努力解决如何/在哪里放置环境对象在我的应用程序环境中以及如何将其连接到我的内容视图/其他视图。

这段代码应该放在哪里?它会进入内容视图吗?

class UserSettings: ObservableObject {
@Published var score = 0
}
Run Code Online (Sandbox Code Playgroud)

有人能帮忙解决这个问题吗?我会很感激 :)

swiftui environmentobject ios14 xcode12

3
推荐指数
1
解决办法
949
查看次数

如何在 SwiftUi (iOS 15 / Xcode 13.2.1) 的 AppDelegate 中使用我的 @EnvironmentObject?

我有一堂课:

class AppInfos_M: ObservableObject {
    @Published var currentUser: User_M = User_M()
    @Published var userTo: User_M = User_M()
}
Run Code Online (Sandbox Code Playgroud)

我声明它main并传递到我的视图environmentObject

...

@main
struct TestApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
...

    @StateObject var appInfos_M = AppInfos_M()
    
    var body: some Scene {
        WindowGroup {
            LaunchScreen_V()
                .environmentObject(appInfos_M)
...
 
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

该课程在我的应用程序中运行得非常好。现在我需要从 修改它AppDelegate,因为我需要appInfos_M.userTo.id在收到通知时获取。我尝试了几件事,但没有一个有效。我怎样才能访问它?

在我需要它的所有视图中,我声明这种方式并且它工作正常,但不是在AppDelegate,为什么?:

 @EnvironmentObject var appInfos_M: AppInfos_M
Run Code Online (Sandbox Code Playgroud)

这是我尝试过但不起作用的测试之一:

...

class AppDelegate: NSObject, UIApplicationDelegate { ... }

...

@available(iOS 10, *)
extension AppDelegate : …
Run Code Online (Sandbox Code Playgroud)

ios appdelegate swiftui environmentobject

2
推荐指数
1
解决办法
1488
查看次数

SwiftUI:环境对象发布者不会在 onReceive 中发送更新

我有一个网络监视器,我想在状态发生变化时接收通知。
看起来像这样:

 final class NetworkMonitor: ObservableObject {
    let monitor = NWPathMonitor()
    let queue = DispatchQueue(label: "Monitor")

    static let shared = NetworkMonitor()

    @Published var status: NetworkStatus = .connected

    func start() {
        self.monitor.pathUpdateHandler = { [weak self] path in
            guard let self = self else { return }
            DispatchQueue.main.async {
                self.status = (path.status == .satisfied) ? .connected : .disconnected
            }
        }

        self.monitor.start(queue: self.queue)
    }
}
Run Code Online (Sandbox Code Playgroud)

我在 Home 中创建一个网络监视器的@StateObject并通过环境对象发送它。

struct HomeView: View {
    @StateObject var networkMonitor = NetworkMonitor()

    var body: some …
Run Code Online (Sandbox Code Playgroud)

ios swift swiftui environmentobject

1
推荐指数
1
解决办法
557
查看次数