SwiftUI: всплывающее окно не увольняет - PullRequest
1 голос
/ 10 февраля 2020

В списке Swift-UI (iOS), показывающем некоторые элементы CoreData, я хочу показать всплывающее окно для каждого элемента для изменения атрибута элемента CoreData.

В приведенном ниже коде это невозможно закрыть всплывающее окно.
Если я удаляю .id(UUID()) из списка, он работает нормально.

В моем приложении требуется .id(UUID()), потому что я изменяю предикат "на fly "и это единственный способ, который я знаю, чтобы избежать того, что SwiftUI пытается сравнить все элементы List старого и нового результата. Эта проблема производительности обсуждалась в Проблема производительности со списком SwiftUI

Есть идеи, как решить эту проблему?

import Foundation
import SwiftUI

struct ContentView: View {
  @FetchRequest(entity: Item.entity(), sortDescriptors: [], predicate: nil) var items: FetchedResults<Item>

  var body: some View {
    VStack
    { Button("Create Testdata"){createTestdata()}
      List(items, id: \.self)
      { item in
        Line(item: item)
      }.id(UUID())
    }
  }
}

struct Line: View {
  @ObservedObject var item : Item
  @State var showSheet = false

  var body: some View {
    Text(item.text!)
    .onLongPressGesture {
      self.showSheet.toggle()// = true
    }
    .popover( isPresented: self.$showSheet,
              arrowEdge: .trailing
            )
    { Pop(showSheet: self.$showSheet, item: self.item )
    }
  }
}

struct Pop: View {
  @Binding var showSheet: Bool
  var item : Item
    //@Environment(\.presentationMode) var presentationMode

    var body: some View {
        VStack {
           Text("CHANGE TO XXXXXXXXX")
            .onTapGesture
            { self.item.text = "XXXXXXX"
              self.showSheet = false
            }
            Text("CHANGE TO YYYYYYYYY")
            .onTapGesture
            { self.item.text = "YYYYYY"
              self.showSheet = false
            }
            Button("Cancel")
            {
                #if os(OSX)
                NSApp.sendAction(#selector(NSPopover.performClose(_:)), to: nil, from: nil)
                #else
                //self.presentationMode.wrappedValue.dismiss() // << behaves the same as below
                self.showSheet = false
                #endif
            }
        }
    }
}

...