标签: observedobject

SwiftUI 表未正确取消初始化关联实例

我\xe2\x80\x99在 SwiftUI 中遇到了与工作表演示相关的令人费解的行为。关闭工作表时,我注意到关联的实例(工作表\xe2\x80\x99s 视图持有的视图模型)don\xe2\x80\x99t 似乎已正确取消初始化。

\n

根据我的测试,唯一deinit按预期被调用的场景是使用@StateObject. 相反,@ObservedObject@Observable宏 don\xe2\x80\x99t 似乎都会触发调用deinit

\n

下面,我\xe2\x80\x99ve提供了一组展示各种场景的示例。每个尝试以不同的方式提供视图模型。要测试解雇,您只需在显示的工作表上向下滑动即可:

\n
import SwiftUI\n\n// ============================================================================ //\n// MARK: - App\n// ============================================================================ //\n\n@main\nstruct SwiftUISheetDeinitIssueApp: App {\n    var body: some Scene {\n        WindowGroup {\n            CaseA_ContentView()\n        }\n    }\n}\n\n// ============================================================================ //\n// MARK: - Case A: @StateObject (Works!)\n// ============================================================================ //\n\nstruct CaseA_ContentView: View {\n    @State var isPresented = false\n    \n    var body: some View {\n        Button("Show Sheet") {\n            self.isPresented = true\n        }\n        .sheet(isPresented: $isPresented) {\n            CaseA_SheetView()\n …
Run Code Online (Sandbox Code Playgroud)

swiftui observedobject swiftui-sheet

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

SwiftUI:当我执行函数时如何从观察到的对象中捕获变化的值

我在 SwiftUI 中观察到的对象有问题。我可以在 View 结构上看到观察对象的变化值。但是在类或函数中,即使我更改了 TextField(可观察对象)的文本值,但“self.codeTwo.text 仍然没有改变。

这是我的代码示例(这是我的 ObservableObject)

class settingCodeTwo: ObservableObject {

private static let userDefaultTextKey = "textKey2"
@Published var text: String = UserDefaults.standard.string(forKey: settingCodeTwo.userDefaultTextKey) ?? ""

private var canc: AnyCancellable!

     init() {
        canc = $text.debounce(for: 0.2, scheduler: DispatchQueue.main).sink { newText in
        UserDefaults.standard.set(newText, forKey: settingCodeTwo.userDefaultTextKey)

    }
}


   deinit {
     canc.cancel()
   }

}
Run Code Online (Sandbox Code Playgroud)

主要问题是......“self.codeTwo.text”从未改变!

class NetworkManager: ObservableObject {


@ObservedObject var codeTwo = settingCodeTwo()
@Published var posts = [Post]()


func fetchData() {
    var urlComponents = URLComponents()
    urlComponents.scheme = "http"



    urlComponents.host = …
Run Code Online (Sandbox Code Playgroud)

ios swiftui combine observedobject observableobject

6
推荐指数
2
解决办法
7509
查看次数

SwiftUI 将数组元素作为绑定传递给子视图

我尝试制作我的第一个 iOS 应用程序,但遇到以下问题,但我不明白如何解决它。我有一个选项卡式 MainPageView,我在其中加载所有数据,然后将其传递到不同的视图。当我在任务视图中添加新项目时,新项目会出现在列表中,但当发生某些情况(例如使用上下文菜单将任务标记为已完成)时,我也想更新任务视图

任务结构:

struct Task: Identifiable, Hashable {
     var name: String = ""
     var status: Bool = false
     var notify: Bool = false
Run Code Online (Sandbox Code Playgroud)

MainPageView - 这里的任务位于 Firebase 观察下,因此当数据库中发生更改时它应该自动更新

struct MainPageView: View {
     @State private var tasks: [Task] = []
     ...
     var body: Some View{
          TabView{
             TaskPageView(tasklist: self.$tasks) ...
Run Code Online (Sandbox Code Playgroud)

任务页面视图

struct TaskPageView: View {
     @Binding var tasklist: [Task]
     ...
     var body: some View{
          NavigationView{
             List{
               ForEach(self.tasklist, id:\.self){ task in
                   NavigationLink(destination: TaskDetView(task: task)){
                        TaskView(name: task.name, done: task.status, notify: task.notify).contextMenu{
                           Button(action: …
Run Code Online (Sandbox Code Playgroud)

xcode binding swiftui observedobject

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

@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 ObservableObject 未更新

我有一个视图和一个 viewModel,当用户添加到用户数组时,它们应该更新 ListView。我可以验证是否已添加用户,但 ObservedObject 并未更新。

我有一个搜索栏,可让您搜索用户,然后更新 ViewModel 中的用户数组,该数组应该更新视图,但事实并非如此。

视图模型

class UsersViewModel: ObservableObject {
    @Published var users: [User] = []
    @Published var isLoading = false
    var searchText: String = ""
    
    func searchTextDidChange() {
        isLoading = true
        API.User.searchUser(text: searchText) { (users) in
            self.isLoading = false
            self.users = users
        }
        // confirmed that users has data now at this point
    }
}
Run Code Online (Sandbox Code Playgroud)

看法

struct UsersView: View {
    @ObservedObject var usersViewModel = UsersViewModel()
    
    var body: some View {
        VStack() {
            SearchBarView(text: $usersViewModel.searchText, onSearchButtonChanged: usersViewModel.searchTextDidChange) …
Run Code Online (Sandbox Code Playgroud)

observable swiftui observedobject observableobject

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

@Published 数组中 ObservableObject 的更改不会更新视图

我已经在 SwiftUI 的问题上苦苦挣扎了几个小时。

这是我的问题的一个简化示例:

class Parent: ObservableObject {
    @Published var children = [Child()]
}

class Child: ObservableObject {
    @Published var name: String?

    func loadName() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
            // Async task here...
            self.objectWillChange.send()
            self.name = "Loaded name"
        }
    }

}

struct ContentView: View {
    @ObservedObject var parent = Parent()

    var body: some View {
        Text(parent.children.first?.name ?? "null")
            .onTapGesture {
                self.parent.objectWillChange.send()
                self.parent.children.first?.loadName() // does not update
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个 ObservableObject(父级),存储 ObservableObjects(子级)的 @Published 数组。

问题是,当通过数组中一个对象上的异步任务更改名称属性时,视图不会更新。

你有什么主意吗 ?

非常感谢尼古拉斯

swift swiftui combine observedobject

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

更新 SwiftUI 中树形结构的 UI

我有一个 ObservableObject 类,Model0它有一个Publishedobject nested。该nested对象表示一个递归树结构。我希望能够更新树结构并适当更新 UI。但是,在下面的代码中,当我更新对象的子对象时nested,UI 不会更新,我认为是因为对对象的引用nested没有更改。nested当我更改树结构中的任何对象时,如何更新 UI ?

class Nested: Identifiable {
    var id: UUID = UUID()
    var name: String
    var children:[Nested]
    
    init(name: String, children:[Nested]) {
        self.children = children
        self.name = name
    }
}

class Model0 : ObservableObject {
    @Published var nested: Nested
    
    init(nested: Nested) {
        self.nested = nested
    }
    
    func update() {
        nested.children[0] = Nested(name:"New", children: [])
    }
}

struct NestedView: View {
    var nested: Nested …
Run Code Online (Sandbox Code Playgroud)

tree children swift swiftui observedobject

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

@State 和 @ObservedObject 有什么区别,它们都可以用来持久化状态吗?

当我在 Google 上搜索“State vs ObservedObject”时,第一个结果来自 Hacking with Swift,它说@ObservedObject

这与@State 非常相似,除了现在我们使用的是外部引用类型,而不是像字符串或整数这样的简单本地属性。

我可以@ObservedObject用来创建持久化状态吗?它是否像简单@State属性和@ObservedObject复杂对象一样简单,还是有更多细微差别?

swiftui observedobject

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

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
查看次数

如何正确使用 SwiftUI 已发布的可选属性

为了提供一些背景信息,我正在编写我们应用程序的订单跟踪部分,该部分会经常从服务器重新加载订单状态。屏幕上的 UI 是用 SwiftUI 开发的。我需要屏幕上有一个可选图像,该图像随着订单的进展而变化。

当我尝试以下操作时,一切正常......

我的 viewModel 是一个 ObservableObject: internal class MyAccountOrderViewModel: ObservableObject {

这有一个已发布的属性: @Published internal var graphicURL: URL = Bundle.main.url(forResource: "tracking_STAGEONE", withExtension: "gif")!

在 SwiftUI 中使用该属性如下: GIFViewer(imageURL: $viewModel.graphicURL)


我的问题是该graphicURL属性的占位符值可能不正确,而我的要求是它是可选的。将已发布的属性更改为:@Published internal var graphicURL: URL?会导致我的 GIFViewer 出现问题,它不接受可选 URL:

Cannot convert value of type 'Binding<URL?>' to expected argument type 'Binding<URL>'

尝试明显展开 会graphicURL产生此错误:

Cannot force unwrap value of non-optional type 'Binding<URL?>'


使这项工作有效的正确方法是什么?我不想在属性中添加一个值,并检查该属性是否等于占位符值(即将其视为 nil),或者假设该属性始终为非 nil 并以某种方式不安全地强制解开它。

swiftui swift-optionals observedobject

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