当数组更改时,SwiftUI ForEach 不会迭代。列表为空且 ForEach 确实运行

标签 swift swiftui

我正在尝试将 MultiPeer Connectivity 框架与 swift ui 结合使用,但在我看来,使用 ForEach 时遇到问题。我有一个单例,用于跟踪数组中的连接用户:

class MPCManager: NSObject {
    static let instance = MPCManager()
    var devices: [Device] = []
...

我的设备类别:

class Device: NSObject {
    let peerID: MCPeerID
    var session: MCSession?
    var name: String
    var state = MCSessionState.notConnected
    var lastMessageReceived: Message?
...
}

当 MultiPeer 连接帧找到新的对等点时,MPCManager 会将新设备添加到阵列中。我已经在调试器中确认了这一点。当我尝试在列表中显示设备时出现问题。这是我正在使用的代码:

struct ContentView : View {
    var devices: [Device] = MPCManager.instance.devices
    var body: some View {
        List {
            ForEach(self.devices.identified(by: \.name)) { device in
                Text(device.name)
            }
        }
    }
}

当应用程序启动时,会显示列表,但它是空的。当我在 ForEach 内的 View 代码中放置断点时,执行永远不会停止。当我将数组更改为硬编码值列表时,它显示得很好。我还尝试直接在我的 View 中引用静态实例中的数组,如下所示:

ForEach(self.devices.identified(by: \.name)) { device in
    Text(device.name)
}

还是什么都没有。我对 Swift 很陌生,所以可能有一些简单的东西我错过了,但我只是没有看到它。有什么想法吗?

最佳答案

据我所知,这里存在几个问题。

首先,我建议您使用 MPCManager 尝试此操作:

import SwiftUI
import Combine

class MPCManager: NSObject, BindableObject {
    var didChange = PassthroughSubject<Void, Never>()

    var devices: [Device] = [] {
        didSet {
            self.didChange.send(())
        }
    }
}

然后,在您的 ContentView 中执行以下操作:

struct ContentView : View {
    @ObjectBinding var manager: MPCManager = MPCManager()

    var body: some View {
        List {
            ForEach(self.manager.devices.identified(by: \.name)) { device in
                Text(device.name)
            }
        }
    }
}

回答你的问题的主要困难是我无法运行你的代码。如果您可以将代码提炼为可能知道答案的人可以复制并粘贴到 Xcode 中的内容,那么您的问题对其他人会更有用(并且更容易回答)。

更新

从 Xcode Beta 4 开始,identified(by:) 已被 ListForEach 的特定初始化程序取代,从 Xcode 开始Beta 5 中,BindableObject 已替换为 ObservableObject@ObjectBinding 已替换为 @ObservedObject

import SwiftUI
import Combine

class MPCManager: NSObject, ObservableObject {
    var objectWillChange = PassthroughSubject<Void, Never>()

    var devices: [Device] = [] {
        willSet {
            self.objectWillChange.send()
        }
    }
}
struct ContentView : View {
    @ObservedObject var manager: MPCManager = MPCManager()

    var body: some View {
        List {
            ForEach(self.manager.devices, id: \.name) { device in
                Text(device.name)
            }
        }
    }
}

关于当数组更改时,SwiftUI ForEach 不会迭代。列表为空且 ForEach 确实运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57023712/

相关文章:

ios - func return does notReturn String from my conform to protocol StringLiteralConvertible 错误

ios - SwiftUI:如何在列表内正确设置内容大小变化的动画?

SwiftUI ActionSheet 选择器

swiftui - 在没有导航链接的情况下更改 View SwiftUI

swift - 如何更改应用程序色调颜色(新的 SwiftUI 生命周期应用程序)?

ios - ScrollView : unexpectedly found nil while unwrapping an Optional value

ios - 推送通知中的自定义按钮操作

swift - 如何创建一个 View ,该 View 接受一个 Binding 并将其传递给 View 中的另一个 Binding - SwiftUI

ios - 格式化为 2 位小数 (NSDecimalNumber)

fonts - 使用 SwiftUI 设置导航栏标题字体