Свифтуи лист неожиданно увольняет и перемещается обратно после редактирования связанных данных в вложенном навигационномIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Свифтуи лист неожиданно увольняет и перемещается обратно после редактирования связанных данных в вложенном навигационном

Сообщение Anonymous »

Я работаю над приложением Swiftui, чтобы управлять рецептами. Я представляю список рецептов в рецепте списка , и когда пользователь нажимает на один, я перейду к ReceedEtailView . Внутри этого подробного представления я позволяю пользователю отредактировать рецепт через .sheet , содержащий ModifyRecipeview .
Вот как работает поток:
1. RecepesListView.swift

Код: Выделить всё

NavigationLink(recipe.mainInformation.name, destination: RecipeDetailView(recipe: binding(for: recipe)))
< /code>

 2. RecemedetailView.swift 

Код: Выделить всё

struct RecipeDetailView: View {
@Binding var recipe: Recipe
@State private var isPresented = false

var body: some View {
VStack {
// ... recipe details shown here
}
.navigationTitle(recipe.mainInformation.name)
.toolbar {
ToolbarItem {
Button("Edit") {
isPresented = true
}
}
}
.sheet(isPresented: $isPresented) {
NavigationStack {
ModifyRecipeView(recipe: $recipe)
.toolbar {
ToolbarItem(placement: .confirmationAction) {
Button("Save") {
isPresented = false
}
}
}
.navigationTitle("Edit Recipe")
}
}
}
}
< /code>
 3. ModifyRecipeView.swift 

Код: Выделить всё

struct ModifyRecipeView: View {
@Binding var recipe: Recipe
@State private var selection: Selection = .main

enum Selection: String, CaseIterable {
case main = "Main"
case ingredients = "Ingredients"
case directions = "Directions"
}

var body: some View {
VStack {
Picker("Options", selection: $selection) {
ForEach(Selection.allCases, id: \.self) { selection in
Text(selection.rawValue)
}
}
.pickerStyle(SegmentedPickerStyle())

switch selection {
case .main:
ModifyMainInformationView(mainInformation: $recipe.mainInformation)
case .ingredients:
ModifyComponentsView(components: $recipe.ingredients)
case .directions:
ModifyComponentsView(components: $recipe.directions)
}

Spacer()
}
}
}
< /code>
 4.  ModifyComponentSview.swift 

Код: Выделить всё

struct ModifyComponentsView: View
where DestinationView.Component == Component {

@Binding var components: [Component]
@State var newComponent: Component = Component()

var body: some View {
VStack {
let destination = DestinationView(component: $newComponent) { component in
components.append(component)
DispatchQueue.main.async {
newComponent = Component()
}
}

if components.isEmpty {
NavigationLink(destination: destination) {
Text("Add the first \(Component().instanceName)")
}
} else {
HStack {
Text(Component().pluralName().capitalized)
.font(.title).fontWeight(.bold)
.padding()
Spacer()
EditButton().padding()
}

List {
ForEach(components.indices, id: \.self) { i in
NavigationLink(destination: modifyComponent(i)) {
Text(components[i].description)
}
}
.onDelete { components.remove(atOffsets: $0) }
.onMove { indices, newOffset in
components.move(fromOffsets: indices, toOffset: newOffset)
}
}

Spacer()

NavigationLink(destination: destination) {
Text("Add New \(Component().pluralName())")
}
}
}
}

func modifyComponent(_ i: Int) -> some View {
DestinationView(component: $components[i]) { _ in return }
.navigationTitle("Edit \(components[i].instanceName)")
}
}
< /code>
 5.  Моя модель настройка (Recipe
, ингредиент , direction )
Чтобы исключить проблемы с идентичностью модели или структурой, вот определение моих основных типов:

Код: Выделить всё

struct Recipe: Identifiable {
var id = UUID()
var mainInformation: MainInformation
var ingredients: [Ingredient]
var directions: [Direction]
var isFavorite: Bool = false

init(mainInformation: MainInformation, ingredients: [Ingredient], directions: [Direction]) {
self.mainInformation = mainInformation
self.ingredients = ingredients
self.directions = directions
}

init() {
self.init(
mainInformation: MainInformation(name: "", description: "", author: "", category: .breakfast),
ingredients: [],
directions: []
)
}

var isValid: Bool {
mainInformation.isValid && !ingredients.isEmpty && !directions.isEmpty
}
}

struct MainInformation {
var name: String
var description: String
var author: String
var category: Category

var isValid: Bool {
!name.isEmpty && !description.isEmpty && !author.isEmpty
}
}

struct Ingredient: RecipeComponent {
var name: String
var quantity: Double
var unit: Unit
var instanceName: String = "ingredient"

var description: String {
let formattedQuantity = String(format: "%g", quantity)
switch unit {
case .none:
let formattedName = quantity == 1 ? name : name + "s"
return "\(formattedQuantity) \(formattedName)"
default:
return quantity == 1 ? "1 \(unit.rawValue) \(name)" : "\(formattedQuantity) \(unit.plural) \(name)"
}
}

init(name: String, quantity: Double, unit: Unit) {
self.name = name
self.quantity = quantity
self.unit = unit
}

init() {
self.init(name: "", quantity: 0, unit: .none)
}
}

struct Direction: RecipeComponent {
var description: String
var isOptional: Bool
var instanceName: String = "direction"

init(description: String, isOptional: Bool) {
self.description = description
self.isOptional = isOptional
}

init() {
self.init(description: "", isOptional: false)
}
}

enum Category: String, CaseIterable {
case breakfast = "Breakfast"
case lunch = "Lunch"
case dinner = "Dinner"
case dessert = "Dessert"
case snack = "Snack"
}

enum Unit: String, CaseIterable {
case teaspoon = "Teaspoon"
case tablespoon = "Tablespoon"
case ounce = "Ounce"
case cup = "Cup"
case pound = "Pound"
case gram = "Gram"
case milliliter = "Milliliter"
case liter = "Liter"
case piece = "Piece"
case kilogram = "Kilogram"
case none = "No Unit"

var plural: String {
return self.rawValue + "s"
}
}
The problem:
As soon as I delete or reorder an item in the ingredients or directions sections within the ModifyRecipeView sheet, the .sheet unexpectedly closes, and SwiftUI navigates Back к основному рецепту списка .
Есть нет явного .dismiss () вызовы в операциях удаления или перемещения.

Код: Выделить всё

Button("Save") {
createAction(ingredient)
dismiss()
}
this dimiss () оценивается в представление детской формы, а не для внешнего листа. Все же, что, по -видимому, возникает во время любой мутации рецепта. В граничном массиве лист ModifyRecipeView закрывается. что редактирование рецепта на месте через привязки является признанием внутренней иерархии навигации Swiftui.

Код: Выделить всё

RecipeDetailView
) исчезнуть и запустить как листовое увольнение, так и навигационное поп. Идентифицируемый и имеет стабильный uuid , который не изменяется во время изменений. С операторами печати, чтобы проследить поток состояния recipe.ingredients и recipe.warections , и подтвердила, что мутация запускает исчезновение receedetailview .
[*] 🧪 I попыталась удалить .Ondelete . Причина.
[*] 💡 Я рассмотрел вопрос о редактировании A Copy рецепта (с использованием @state ) Inside ModifyRecipeView и применение изменений только при нажатии «Сохранить», но я не уверен, что это лучший архитектурный подход при использовании глубоких вложенных связей. Университетский поток данных еще (например, хранение состояния редактирования в модели представления), хотя я подозреваю, что это может помешать Swiftui неверно истолковывать мутации в качестве изменений идентичности.


Подробнее здесь: https://stackoverflow.com/questions/796 ... bound-data
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»