SwiftUI @StateObject 无法刷新视图
SwiftUI @StateObject couldn't refresh view
我在 ContentView 页面上看不到 Text 对象的变化。但是,当我 运行 .onReceive 中的相同代码与打印时,我可以看到更改。这里有什么问题?
我想从不同的地方管理游戏的状态,从不同的地方管理游戏的运行。是我逻辑错了吗?
枚举
enum GameSituation {
case play
}
游戏配置
class GameConfig: ObservableObject {
@Published var randomCellValue: Int = 0
@Published var timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
func startGame() {
determineRandomCell()
}
func determineRandomCell() {
randomCellValue = Int.random(in: 0...11)
}
func playSound(soundfile: String, ofType: String) {
if let path = Bundle.main.path(forResource: soundfile, ofType: ofType){
do{
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch {
print("Error")
}
}
}
}
比赛情况
class GameSituations: ObservableObject {
@Published var gameConfig = GameConfig()
func gameSituation(gameSituation: GameSituation) {
switch gameSituation {
case .play:
gameConfig.startGame()
}
}
}
内容视图
struct ContentView: View {
@StateObject var gameSituation = GameSituations()
var body: some View {
Text("\(gameSituation.gameConfig.randomCellValue)")
.padding()
.onReceive(gameSituation.gameConfig.timer, perform: { _ in
gameSituation.gameSituation(gameSituation: .play)
print("random: \(gameSituation.gameConfig.randomCellValue)")
})
}
}
你有多个问题我都解决了,你的第一个也是最大的问题是,你正在初始化一个 ObservableObject 的实例,但使用另一个!第二个是您忘记在视图中使用 GameConfig 的 StateObject,正如您在代码中看到的那样,您确实使用了 GameSituations 的 StateObject 但没有GameConfig,要问为什么,因为是Publisher!
我最好的建议:尝试只使用一个 ObservableObject!使用 2 个具有绑定的不同 ObservableObject 有这样一个问题,您可以看到!尝试将所有代码组织到一个 ObservableObject.
enum GameSituation {
case play
}
class GameConfig: ObservableObject {
static let shared: GameConfig = GameConfig() // <<: Here
@Published var randomCellValue: Int = 0
@Published var timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
func startGame() {
determineRandomCell()
}
func determineRandomCell() {
randomCellValue = Int.random(in: 0...11)
}
func playSound(soundfile: String, ofType: String) {
print(soundfile)
}
}
class GameSituations: ObservableObject {
static let shared: GameSituations = GameSituations() // <<: Here
let gameConfig = GameConfig.shared // <<: Here
func gameSituation(gameSituation: GameSituation) {
switch gameSituation {
case .play:
gameConfig.startGame()
}
}
}
struct ContentView: View {
@StateObject var gameSituation = GameSituations.shared // <<: Here
@StateObject var gameConfig = GameConfig.shared // <<: Here
var body: some View {
Text(gameConfig.randomCellValue.description) // <<: Here
.onReceive(gameConfig.timer, perform: { _ in // <<: Here
gameSituation.gameSituation(gameSituation: .play)
print("random: \(gameSituation.gameConfig.randomCellValue)")
})
}
}
我在 ContentView 页面上看不到 Text 对象的变化。但是,当我 运行 .onReceive 中的相同代码与打印时,我可以看到更改。这里有什么问题?
我想从不同的地方管理游戏的状态,从不同的地方管理游戏的运行。是我逻辑错了吗?
枚举
enum GameSituation {
case play
}
游戏配置
class GameConfig: ObservableObject {
@Published var randomCellValue: Int = 0
@Published var timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
func startGame() {
determineRandomCell()
}
func determineRandomCell() {
randomCellValue = Int.random(in: 0...11)
}
func playSound(soundfile: String, ofType: String) {
if let path = Bundle.main.path(forResource: soundfile, ofType: ofType){
do{
audioPlayer = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))
audioPlayer.prepareToPlay()
audioPlayer.play()
} catch {
print("Error")
}
}
}
}
比赛情况
class GameSituations: ObservableObject {
@Published var gameConfig = GameConfig()
func gameSituation(gameSituation: GameSituation) {
switch gameSituation {
case .play:
gameConfig.startGame()
}
}
}
内容视图
struct ContentView: View {
@StateObject var gameSituation = GameSituations()
var body: some View {
Text("\(gameSituation.gameConfig.randomCellValue)")
.padding()
.onReceive(gameSituation.gameConfig.timer, perform: { _ in
gameSituation.gameSituation(gameSituation: .play)
print("random: \(gameSituation.gameConfig.randomCellValue)")
})
}
}
你有多个问题我都解决了,你的第一个也是最大的问题是,你正在初始化一个 ObservableObject 的实例,但使用另一个!第二个是您忘记在视图中使用 GameConfig 的 StateObject,正如您在代码中看到的那样,您确实使用了 GameSituations 的 StateObject 但没有GameConfig,要问为什么,因为是Publisher!
我最好的建议:尝试只使用一个 ObservableObject!使用 2 个具有绑定的不同 ObservableObject 有这样一个问题,您可以看到!尝试将所有代码组织到一个 ObservableObject.
enum GameSituation {
case play
}
class GameConfig: ObservableObject {
static let shared: GameConfig = GameConfig() // <<: Here
@Published var randomCellValue: Int = 0
@Published var timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
func startGame() {
determineRandomCell()
}
func determineRandomCell() {
randomCellValue = Int.random(in: 0...11)
}
func playSound(soundfile: String, ofType: String) {
print(soundfile)
}
}
class GameSituations: ObservableObject {
static let shared: GameSituations = GameSituations() // <<: Here
let gameConfig = GameConfig.shared // <<: Here
func gameSituation(gameSituation: GameSituation) {
switch gameSituation {
case .play:
gameConfig.startGame()
}
}
}
struct ContentView: View {
@StateObject var gameSituation = GameSituations.shared // <<: Here
@StateObject var gameConfig = GameConfig.shared // <<: Here
var body: some View {
Text(gameConfig.randomCellValue.description) // <<: Here
.onReceive(gameConfig.timer, perform: { _ in // <<: Here
gameSituation.gameSituation(gameSituation: .play)
print("random: \(gameSituation.gameConfig.randomCellValue)")
})
}
}