I'm trying to build an 2048 game to learn SwiftUI but I'm stuck. I have three classes, Game, Board and Tiles. Game has a variable that contains an instance of Board and board has a variable that contains a matrix of Tiles.
In the same way, I have three views, ContentView.swift, BoardView.swift and TilesView.swift
In the view ContentView.swift I initialize Game like this :
@ObservedObject var game = Game()
...
Blocks(board: self.game.board)
Then in BoardView.swift :
@ObservedObject var board: Board
... Loop ...
TileView(value: self.board.board[y][x].value)
...
.gesture(
DragGesture()
.onChanged({ value in
let direction = self.board.gestureToDirection(startLocation: value.startLocation, location: value.location)
self.board.move(direction: direction)
})
)
And in TileView.swift :
@State var value: Int = 0;
Game.swift :
class Game: ObservableObject {
@Published var board = Board()
}
Board.swift :
class Board: ObservableObject {
@Published var board: [[Tile]] = []
/* Here is the logic of the game, when a gesture is triggered in ContentView.swift, I call a function to move the tiles */
}
Tiles.swift :
class Tile: ObservableObject {
@Published var coords: Coords
@Published var value: Int
}
My problem is that when I drag on the screen, the board doesn't change, and I have the feeling that the content of my board is not the same in my different files ...
How can I share data between view and classes ?
Thanks.
I believe this is because the @Published
changes are not published through the board: [[Tile]]
array. I have run into similar issues, here for example.
One thing to try would be to give each Tile
object a reference back to the Board
that owns it, and manually trigger the board's objectWillChange
when changes need publishing.
I would recommend the following changes (scratchy):
1) Make a model, Tile
, a value type
struct Tile {
var coords: Coords
var value: Int
}
2) Make a TileView
present, as it sounds, a Tile
, and give it a model as binding (@State is for internal usage, take a habit to give it private
)
struct TileView: View {
@Binding var model: Tile
...
3) make a bind between views
TileView(model: self.$board.board[y][x])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.