标签: observableobject

在 ObservableObject 中引用 EnvironmentObject

如果用户未登录,我有一个 LoginView 显示一个 RegisterView,如果他登录则显示一个 ContentView:

struct LoginView: View {
    @EnvironmentObject var userManager: UserManager
    var body: some View {
        Group {
            if userManager.isRegistered {
                ContentView()
            } else {
                RegisterView()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ContentView具有三个ObservedObject属性,使用组合从带有其余 api 的服务器获取内容。

struct ContentView: View {
    @EnvironmentObject var userManager: UserManager
    @ObservedObject var usersStore = UsersStore()
    @ObservedObject var rolesStore = RolesStore()
    @ObservedObject var elementsStore = ElementsStore()

    var body: some View {
        NavigationView {
            ZStack {
                Image("stell")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .opacity(0.1)

                VStack(alignment: .leading, spacing: 5) { …
Run Code Online (Sandbox Code Playgroud)

swiftui combine observableobject

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

发布值时 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
查看次数

如何以动画方式删除使用 ForEach 循环创建的视图,并从 SwiftUI 中的 ObservableObject 获取数据

该应用程序具有以下设置:

我的主视图使用 SwiftUI 循环创建标签云ForEach。从被调用的数组中获取ForEach数据。使用 a ,每三秒向数组添加一个新标签。通过添加标签,会再次触发并创建另一个. 一旦将三个以上的标签添加到数组中,就会从数组中删除第一个(最旧的)标签,并且 ForEach 会删除该特定的。@PublishedObservableObjectTagModelTimerObservableObjectForEachTagViewObservableObjectTagView

存在以下问题:

TagView 的创建非常完美。它还使用动画和 .onAppear 修饰符以应有的方式进行动画处理TagView。然而,当最旧的标签被删除时,它不会动画化其删除。中的代码.onDisappear会执行,但TagView会立即被删除。

我尝试了以下方法来解决该问题:

我尝试通过使用重复然后自动反转的动画来让整个出现和消失的动画TagView在内部运行。.onAppear它有点有效,但这样有两个问题。首先,如果动画时间太短,一旦动画完成并被TagView删除,将在没有应用任何修改器的情况下显示一小会儿,然后它将被删除。其次,如果我将动画持续时间设置得更长,则会TagView在动画完成之前将其删除。为了使其工作,我需要非常精确地计算动画的删除和持续时间,这将使动画TagView非常依赖Timer,这似乎不是一个好的解决方案。

我尝试的另一个解决方案是找到类似于self.presentationMode.wrappedValue.dismiss()使用@Environment(\.presentationMode)变量的东西,并以某种方式TagView.onAppear动画完成后将其自身删除。但这仅适用于在导航堆栈中创建视图并且我找不到任何其他方法来让视图自行销毁的情况。我还认为,一旦TagModel更新其数组,就会再次引起问题。

我阅读了其他几个 SO 解决方案,它们指向 ForEach 循环中的数据枚举。但我将每个 TagView 创建为自己的对象,我认为这不应该是问题,并且我不确定如果这是问题的一部分,我必须如何实现它。

这是我的应用程序的简化代码,可以在 iOS 单视图 SwiftUI 项目中运行。

import SwiftUI

struct ContentView: View {
    private let timer = …
Run Code Online (Sandbox Code Playgroud)

foreach animation swift swiftui observableobject

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

SwiftUI 组合:嵌套观察对象

让 swiftUI 仍然基于嵌套观察对象进行更新的最佳方法是什么?

以下示例显示了我对嵌套观察对象的含义。球管理器的 balls 数组是一个已发布的属性,其中包含可观察对象的数组,每个对象本身都有一个已发布的属性(颜色字符串)。

不幸的是,当点击其中一个球时,它不会更新球的名称,也不会收到更新。那么我可能搞砸了在这种情况下联合收割机是如何工作的?

import SwiftUI

class Ball: Identifiable, ObservableObject {
    let id: UUID
    @Published var color: String
    init(ofColor color: String) {
        self.id = UUID()
       self.color = color
    }
}

class BallManager: ObservableObject {
    @Published var balls: [Ball]
    init() {
        self.balls = []
    }
}

struct Arena: View {
   @StateObject var bm = BallManager()

    var body: some View {
        VStack(spacing: 20) {
            ForEach(bm.balls) { ball in
                Text(ball.color)
                    .onTapGesture {
                        changeBall(ball)
                    }
            }
        }
        .onAppear(perform: createBalls)
        .onReceive(bm.$balls, perform: …
Run Code Online (Sandbox Code Playgroud)

swift swiftui combine observableobject

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

SwiftUI - 通过嵌套引用类型传播更改通知

我想将 SwiftUI 中的 ObservableObject 行为扩展到嵌套类,我正在寻找正确的方法来做到这一点。它可以使用Combine“手动”完成,但我想使用SwiftUI有一种更简洁的方法,我希望你能指出我正确的方向。这就是我的意思……

下面是 ObservableObject 的一个典型应用,它使 View 动态响应引用类型的变化。点击按钮切换showText值,使文本在屏幕上出现/消失:

import SwiftUI

class MyClass: ObservableObject {
    @Published var showText = false
}


struct ContentView: View {

    @ObservedObject var instance = MyClass()

    var body: some View {
        VStack(spacing: 10) {
            Button(action: {
                print(self.instance.showText)
                self.instance.showText.toggle()
            }) {
                Text("BUTTON").bold().padding()
                    .foregroundColor(.white)
                    .background(Color.red)
            }
            if instance.showText {
                Text("Hello, World!")
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这工作正常。

但是下面的修改呢,其中包含的类showText是 an InnerClass,它本身包含在 an 中OuterClass?按钮切换showText得很好,但值更改的通知不再通过OuterClass实例传播到视图,因此视图根本不再显示文本。

import SwiftUI

class OuterClass: ObservableObject …
Run Code Online (Sandbox Code Playgroud)

propagation swiftui combine observableobject

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

将数据从 SwiftUI 传递到 UIKit

我是 SwiftUI 的新手,我一直在尝试如何在同一个应用程序中将 SwiftUI 和 UIKit 集成在一起。我用 SwiftUI 制作了一个简单的登录屏幕。

struct LoginView: View {
    
    var body: some View {
        VStack {
            LogoView()
            InputView(title: "Company Code")
            ButtonView(title: "Proceed")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我通过将该视图中的所有组件提取到单独的视图(LogoView、InputView、ButtonView)来使它们可重用。

struct LogoView: View {
    var body: some View {
        VStack {
            Image("logo")
            Text("Inventory App")
                .foregroundColor(.blue)
                .fontWeight(.bold)
                .font(.system(size: 32))
        }
    }
}

struct InputView: View {
    let title: String
    
    @State private var text: String = ""
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(title)
                .foregroundColor(.gray)
                .fontWeight(.medium)
                .font(.system(size: 18))
            
            TextField("", text: …
Run Code Online (Sandbox Code Playgroud)

ios swift swiftui observableobject

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

当我使用属性更新视图时,ObservedObject 会重置。因此会导致数据丢失

我有一个问题,当ViewModel视图更新时会重新初始化。

我有 2 个视图,SongListView它们PlayerView共享一个Player. 当玩家的播放状态改变时(isPlaying == true)viewModelinSongListView重置并变为空数组。因此,我视图中的列表变为空。

在此输入图像描述

歌曲列表查看:

struct SongListView: View {

    @ObservedObject var model: SongListViewModel = SongListViewModel() // This resets when player.isPlaying is set to true

    @ObservedObject var player: Player

    var body: some View {

        List(model.songs, id: \.id) { song in
            Button(action: {
                self.player.play(link: song.link)
            }) {
                TitleRowView(title: song)
            }
        }
        .onAppear {
            self.model.get()
        }
        .navigationBarTitle(Text("Songs"), displayMode: .inline)
    }
}
Run Code Online (Sandbox Code Playgroud)

歌曲列表视图模型:

class SongListViewModel: ObservableObject { …
Run Code Online (Sandbox Code Playgroud)

ios swift swiftui observableobject

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

ObservedObject 更改时的通知

我有一个由几个 SwiftUI 组件组成的图形用户界面(我们称它们为子视图)。这些子视图在 ObservableObject / ObservedObject 的帮助下相互通信。当一个视图发生更改时,另一个视图会自动收到通知并自行更新。

然而,其中一个子视图不是 SwiftUI 视图,而是 SpriteKit SKScene。在这里,我也想对观察值的变化做出反应。但我没有自动更新的视图。我想根据观察到的值对精灵进行调整。

我如何得知价值的变化?我可以在 ObservedObject 的值发生变化时立即调用方法吗?

sprite-kit swift swiftui observedobject observableobject

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

Passing an ObservableObject model through another ObObject?

I feel like I can sort of understand why what I'm doing isn't working but I'm still trying to wrap my head around Combine and SwiftUI so any help here would be welcome.

Consider this example:

Single view app that stores some strings in UserDefaults, and uses those strings to display some Text labels. There are three buttons, one to update the title, and one each to update the two UserDefaults-stored strings to a random string.

The view is a …

ios swift swiftui combine observableobject

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

ObservableObject 与 NWPathMonitor

我尝试使 NWPathMonitor 成为一个可观察对象,如果有网络连接则返回 true,如果没有网络连接则返回 false。

你能帮助我吗,因为我的解决方案不起作用。

谢谢

import Foundation
import Network

class TestNetStatus: ObservableObject {

    let monitor = NWPathMonitor()
    let queue = DispatchQueue.global(qos: .background)

    @Published var connected: Bool = false
    private var isConnected: Bool = false

    init() {
        monitor.start(queue: queue)

        monitor.pathUpdateHandler = { path in
            if path.status == .satisfied {
                self.isConnected = true
            } else {
                self.isConnected = false
            }
        }

        self.connected = isConnected
    }
}

Run Code Online (Sandbox Code Playgroud)

swiftui observableobject

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

SwiftUI:具有计算属性的 ObservableObject

我有一个带有自定义月份选择器的简单视图。每次向左或向右单击 V 形标志时,

在 DateView 中,我有两个私有变量:startDateOfMonth2: DateendDateOfMonth2: Date。但它们仅在 DateView 中可用。

如何使这两个变量在其他视图中可用?

我试图将它们添加为 @Published vars,但出现错误:

属性包装器不能应用于计算属性

我只发现了几个类似的问题,但我无法在我的代码中使用它们的答案。

import SwiftUI

class SelectedDate: ObservableObject {
    @Published var selectedMonth: Date = Date()
    
    @Published var startDateOfMonth2: Date {
        let components = Calendar.current.dateComponents([.year, .month], from: selectedMonth)
        let startOfMonth = Calendar.current.date(from: components)!
        return startOfMonth
    }

    @Published var endDateOfMonth2: Date {
        var components = Calendar.current.dateComponents([.year, .month], from: selectedMonth)
        components.month = (components.month ?? 0) + 1
        let endOfMonth = Calendar.current.date(from: components)!
        return endOfMonth
    } …
Run Code Online (Sandbox Code Playgroud)

ios swift computed-properties swiftui observableobject

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

SwiftUI - 当加载视图后更新属性时,不会调用 onReceive 来更改 ObservableObject 属性

我有一个视图,它在滚动视图中显示从 API 加载的一些照片。我想推迟获取图像直到显示视图。我的观点,简化后看起来像这样:

struct DetailView : View {
    @ObservedObject var viewModel: DetailViewModel

    init(viewModel: DetailViewModel) {
        self.viewModel = viewModel
    }

    var body: some View {
        GeometryReader { geometry in
            ZStack {
                Color("peachLight").edgesIgnoringSafeArea(.all)
                if self.viewModel.errorMessage != nil {
                    ErrorView(error: self.viewModel.errorMessage!)
                } else if self.viewModel.imageUrls.count == 0 {
                    VStack {
                        Text("Loading").foregroundColor(Color("blueDark"))
                        Text("\(self.viewModel.imageUrls.count)").foregroundColor(Color("blueDark"))
                    }
                } else {
                    VStack {
                        UIScrollViewWrapper {
                            HStack {
                                ForEach(self.viewModel.imageUrls, id: \.self) { imageUrl in
                                    LoadableImage(url: imageUrl)
                                        .scaledToFill()
                                }.frame(width: geometry.size.width, height: self.scrollViewHeight)
                            }.edgesIgnoringSafeArea(.all)
                        }.frame(width: geometry.size.width, height: self.scrollViewHeight)
                        Spacer()
                    }
                } …
Run Code Online (Sandbox Code Playgroud)

swiftui combine observableobject

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

当发布的变量更改时,SwiftUI 视图不更新

按下按钮后,我的应用程序会尝试联系 api 来接收数据。然后,该数据存储在可观察对象内的已发布变量中。由于某种原因,在多次按下打开该视图的按钮之前,该视图不会填充数据。我正在寻找在第一次按下按钮时使用从 api 调用收到的信息来更新的视图。我引用的代码如下:

DataFetcher.swift:

class DataFetcher: ObservableObject{
    @Published var dataHasLoaded: Bool = false
    @Published var attendeesLoaded: Bool = false
    @Published var useresUventsLoaded: Bool = false
    @Published var profilesLoaded: Bool = false
    @Published var eventsUpdated: Bool = false
    @Published var events: [eventdata] = []
    @Published var createdEvents: [eventdata] = []
    @Published var profile: profiledata?
    @Published var atendees: [atendeedata] = []
    @Published var IAmAtending: [atendeedata] = []
    @Published var eventNames: [eventdata] = []
    @Published var profileList: [profiledata] = []
    @Published …
Run Code Online (Sandbox Code Playgroud)

view ios swiftui observableobject

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