в файле Maze.swift у меня есть:
var myMaze = Maze() // -> 9.0
определение структуры Maze со следующим содержимым:
@State var widthDouble = 9.0
и метод init()
init() {
print("Maze init:", self.widthDouble) }
В файле ContentView.swift у меня есть следующее:
@State var widthDouble = myMaze.widthDouble
Slider(value: $widthDouble, in: 3...33, step: 1) // updated to 16.0
Button(action: { action() }) { Text("Build maze with updated values") }
и, наконец, функция action()
func action() {
myMaze.widthDouble = widthDouble
print("ContentView: ", widthDouble) // -> 16.0
print("ContentView (myMaze.): ", myMaze.widthDouble) // -> 9.0
myMaze = .init() }
Хотя в func action() myMaze.widthDouble присваивается значение widthDouble (16.0), значение myMaze.widthDouble не обновляется и по-прежнему равно 9.0!
Вывод инициализации(): Инициализация лабиринта: 9.0
Значение 9.0 обновлено до 16.0 в ползунке.
Вывод действия(): КонтентВью: 16.0 ContentView (мой лабиринт): 9.0
Вывод инициализации(): Инициализация лабиринта: 9.0
Может кто-нибудь сказать мне, что не так и почему myMaze.widthDouble не обновляется?
Файл ContentView.swift
//
// ContentView.swift
// Maze
//
// Created by Philippe Lagarrigue on 24/12/2020.
//
import SwiftUI
struct ContentView: View {
@State private var selectedTab = 0
let numTabs = 2
let minDragTranslationForSwipe: CGFloat = 50
var body: some View {
TabView(selection: $selectedTab){
NavigationView{
MenuView()
.navigationBarTitle("Settings")
}
.tabItem {
Image("map")
Text("Map")
}.tag(0)
.highPriorityGesture(DragGesture().onEnded({
self.handleSwipe(translation: $0.translation.width)
}))
NavigationView{
MenuView()
.navigationBarTitle("Settings")
}
.tabItem {
Image("navigation")
Text("Navigation")
}.tag(1)
.highPriorityGesture(DragGesture().onEnded({
self.handleSwipe(translation: $0.translation.width)
}))
}
}
private func handleSwipe(translation: CGFloat) {
if translation > minDragTranslationForSwipe && selectedTab > 0 {
selectedTab -= 1
} else if translation < -minDragTranslationForSwipe && selectedTab < numTabs-1 {
selectedTab += 1
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct MenuView : View {
@State var widthDouble = myMaze.widthDouble
@State var heightDouble = myMaze.heightDouble
@State var oneWay = myMaze.oneWay
@State private var isEditing1 = false
@State private var isEditing2 = false
//@Environment(\.presentationMode) var mode: Binding<PresentationMode>
var body : some View {
HStack(alignment: VerticalAlignment.top) {
VStack(alignment: .leading) {
Text("Number of rooms (horizontally): \(widthDouble, specifier: "%.0f")")
.foregroundColor(isEditing1 ? .red : .black)
Slider(value: $widthDouble, in: 3...33, step: 1,
onEditingChanged: { editing in isEditing1 = editing })
Divider()
// format: "Angle: %.0f", angle
Text("Number of rooms (vertically): \(heightDouble, specifier: "%.0f")")
.foregroundColor(isEditing2 ? .red : .black)
Slider(value: $heightDouble, in: 3...33, step: 1,
onEditingChanged: { editing in isEditing2 = editing })
Divider()
Toggle("One way", isOn: $oneWay)
Button(action: { action() }) { Text("Build maze with updated values") }
} .padding()
}
}
func action() {
myMaze.widthDouble = widthDouble
myMaze.heightDouble = heightDouble
print("ContentView: ", widthDouble, heightDouble)
print("ContentView (myMaze.): ", myMaze.widthDouble, myMaze.heightDouble)
myMaze = .init()
}
}
Файл Maze.swift
//
// Maze.swift
// NewMaze
//
// Created by Philippe Lagarrigue on 23/12/2020.
//
import Foundation
import SwiftUI
let wall = (North: 1, East: 2, South: 4, West: 8) // 15 means all walls
let exit = (toNorth: 16, toEast: 32, toSouth: 64, toWest: 128) // 0 means no exit
var myMaze = Maze()
struct Room {
var x: Int
var y: Int
var roomsToExit: Int
}
struct Maze {
// Properties
var width = 9
var height = 12
var widthDouble = 9.0
var heightDouble = 12.0
var oneWay = true
var exitRoom = Room(x: 0, y: 0, roomsToExit: 0)
var farestRoom = Room(x: 0, y: 0, roomsToExit: 0)
var mazeData = [[Int]]()
var numberOfRooms: Int { return self.width * self.height }
// Methods
init() {
//print(self.widthDouble, self.heightDouble)
self.width = Int(self.widthDouble)
self.height = Int(self.heightDouble)
mazeData = Array(repeating: Array(repeating: 15, count: height), count: width)
print("Maze init:", self.width, "x", self.height)
}
}
Спасибо за ответ, но не могли бы вы сказать мне, как я могу обновить свое значение <myMaze.widthDouble> вне структуры?
@Swiftiti удалите @State из var widthDouble = 9.0 в вашем struct Maze , и он будет работать (Проверено)
Я только что удалил состояние и смог скомпилировать без ошибок, но значение <myMaze.widthDouble> все еще не обновлено!
Немного странно, что вы вызываете init() для вашей переменной лабиринта после того, как вы обновили свойство. Мне кажется, вам нужно два типа: одна модель лабиринта и один строитель лабиринта, скажем, Maze и MazeBuilder. Я бы посоветовал изучить ObservableObject и @Published и использовать их для своего класса строителя.





@State используется для изменений внутри поля зрения@ObservedObject используется для хранения ObservableObject.@Published публикует, когда @Published var изменяется.с этим знанием, вот ответ.
import SwiftUI
struct ContentView: View {
@State private var selectedTab = 0
let numTabs = 2
let minDragTranslationForSwipe: CGFloat = 50
var body: some View {
TabView(selection: $selectedTab){
NavigationView{
MenuView()
.navigationBarTitle("Settings")
}
.tabItem {
Image("map")
Text("Map")
}.tag(0)
.highPriorityGesture(DragGesture().onEnded({
self.handleSwipe(translation: $0.translation.width)
}))
NavigationView{
MenuView()
.navigationBarTitle("Settings")
}
.tabItem {
Image("navigation")
Text("Navigation")
}.tag(1)
.highPriorityGesture(DragGesture().onEnded({
self.handleSwipe(translation: $0.translation.width)
}))
}
}
private func handleSwipe(translation: CGFloat) {
if translation > minDragTranslationForSwipe && selectedTab > 0 {
selectedTab -= 1
} else if translation < -minDragTranslationForSwipe && selectedTab < numTabs-1 {
selectedTab += 1
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct MenuView : View {
@ObservedObject var myMaze = Maze()
@State private var isEditing1 = false
@State private var isEditing2 = false
//@Environment(\.presentationMode) var mode: Binding<PresentationMode>
var body : some View {
HStack(alignment: VerticalAlignment.top) {
VStack(alignment: .leading) {
Text("Number of rooms (horizontally): \(myMaze.widthDouble, specifier: "%.0f")")
.foregroundColor(isEditing1 ? .red : .black)
Slider(value: $myMaze.widthDouble, in: 3...33, step: 1,
onEditingChanged: { editing in isEditing1 = editing })
Divider()
// format: "Angle: %.0f", angle
Text("Number of rooms (vertically): \(myMaze.heightDouble, specifier: "%.0f")")
.foregroundColor(isEditing2 ? .red : .black)
Slider(value: $myMaze.heightDouble, in: 3...33, step: 1,
onEditingChanged: { editing in isEditing2 = editing })
Divider()
Toggle("One way", isOn: $myMaze.oneWay)
Button(action: { action() }) { Text("Build maze with updated values") }
} .padding()
}
}
func action() {
}
}
import Foundation
import SwiftUI
let wall = (North: 1, East: 2, South: 4, West: 8) // 15 means all walls
let exit = (toNorth: 16, toEast: 32, toSouth: 64, toWest: 128) // 0 means no exit
struct Room {
var x: Int
var y: Int
var roomsToExit: Int
}
class Maze: ObservableObject {
@Published var height = 12
@Published var widthDouble = 9.0 {
didSet {
setMezData(height: Int(heightDouble), width: Int(widthDouble))
}
}
@Published var heightDouble = 12.0 {
didSet {
setMezData(height: Int(heightDouble), width: Int(widthDouble))
}
}
@Published var oneWay = true
@Published var exitRoom = Room(x: 0, y: 0, roomsToExit: 0)
@Published var farestRoom = Room(x: 0, y: 0, roomsToExit: 0)
@Published var mazeData = [[Int]]() {
didSet {
print(mazeData)
}
}
var numberOfRooms: Int { return Int(heightDouble) * Int(widthDouble) }
func setMezData(height: Int, width: Int) {
mazeData = Array(repeating: Array(repeating: 15, count: height), count: width)
}
}
Спасибо, я обновил все, как было предложено, и не получил никаких ошибок, но массив mazeData не обновляется новыми значениями, не могли бы вы сказать мне, как я могу его обновить? Наличие < myMaze = .init() > в func action() дает мне следующую ошибку: Невозможно назначить свойство: «я» неизменяемо
Большое спасибо всем вам, теперь все работает, как и ожидалось, и я многому научился!
Где найти эту галочку?
@Swiftiti meta.stackexchange.com/questions/5234/…
с вашей помощью я наконец нашел способ получить доступ к классу из других классов.
// MyClass definition
class MyClass: ObservableObject {
static let sharedInstance = MyClass()
var myProperty = "Something"
...
}
// A struct where I need to use MyClass
struct MyView1 : View {
@ObservedObject var ClassInst = MyClass.sharedInstance
...
ClassInst.myProperty = "Something else"
}
// Another struct where I need to use MyClass
struct MyView2 : View {
@ObservedObject var ClassInst = MyClass.sharedInstance
...
ClassInst.myProperty = "Nothing"
}
@State следует использовать только в представлениях для свойств, обновленных в компоненте пользовательского интерфейса, поэтому вам не следует использовать его в модели (?), Такой как Maze. Кроме этого, я должен сказать, что очень трудно понять, что вы пытаетесь сделать.