मेरे पास स्विफ्टयूआई शीट व्यू है जिसमें ऑब्जर्व्डऑब्जेक्ट है जो टीसीपी संचार को संभालता है, जब यह शीट खारिज हो जाती है तो मुझे इसे अंतिम टीसीपी संदेश भेजने और फिर सॉकेट बंद करने की आवश्यकता होती है। onDisappear घटना कभी भी ट्रिगर नहीं होती है (संपादित करें: अपराधी का पता चला क्योंकि मैं एक UIHostingController का उपयोग करके शीट प्रस्तुत कर रहा हूं, अभी भी एक समाधान की आवश्यकता है मजबूत>) मैंने इसे फॉर्म, नेविगेशन व्यू डालने की कोशिश की है, इसके लिए एक नया स्टैक बनाने की कोशिश की, कुछ भी काम नहीं किया। तो मैंने अपने ObservedObject deinit का उपयोग करने का प्रयास किया है, लेकिन अगर मैं इसे बंद करने के बाद तेजी से फिर से खोलने का प्रयास करता हूं तो यह मुझे खराब पहुंच त्रुटि देता है।

deinit {
    let msg = getUpdatedTimersString()
    self.connection.sendMsg(msg, success: connection.close)
}

मेरे कनेक्शन वर्ग से जो Network Framework का उपयोग करता है

func sendMsg(_ message: String, success: @escaping () -> Void = { }, error: @escaping () -> Void = { }) {
        let msg = message + "\r\n"
        let data: Data? = msg.data(using: .utf8)
        debugPrint("Sending: \(msg)")
        connection.send(content: data, completion: .contentProcessed { (sendError) in
            if let sendError = sendError {
                self.debug("\(sendError)")
                error()
            } else {
                success()
            }
        })
}

func close() {
        connection.cancel()
}

संपादित करें: नीचे दृश्य कोड जोड़ना

struct ScheduleView: View {
    @ObservedObject var scheduleManager = ScheduleManager() // This handles the tcp communication, the deinit you see above is from this

    var body: some View {
        NavigationView {
            Form {
                ForEach(scheduleManager.timers) { timer in
                    ScheduleForm(scheduleManager: self.scheduleManager, timer: timer).onDisappear { debugPrint("schedule form row disappeared") } // This is just a view that adds a section header and a DatePicker to the form for each timer
                }
            }.onDisappear { debugPrint("form disappeared") }

            .navigationBarTitle(Text("Schedule"), displayMode: .inline)
        }.onDisappear() { debugPrint("nav disappeared") }
    }
}

इनमें से कोई भी डिसैपियर मेरे लिए काम नहीं करता है, शेड्यूलफॉर्म पंक्तियों में से केवल एक ही है जो मेरे लिए भी ट्रिगर करता है, लेकिन यह तब ट्रिगर होता है जब शीट बनाई जाती है और हर बार जब मैं एक पंक्ति को दृष्टि से बाहर स्क्रॉल करें, लेकिन तब नहीं जब मैं शीट को खारिज करता हूं।

1
Watermamal 30 जिंदा 2020, 02:33

4 जवाब

सबसे बढ़िया उत्तर

समाधान:

final class ScheduleController: UIHostingController<ScheduleView> {
    required init?(coder: NSCoder) {
        super.init(coder: coder, rootView: ScheduleView())
    }

    init() {
        super.init(rootView: ScheduleView())
    }
    override func viewWillDisappear(_ animated: Bool) {
        rootView.scheduleManager.updateTimers() // this sends the last message
    }

    override func viewDidDisappear(_ animated: Bool) {
        rootView.scheduleManager.connection.close // this closes the connection
    }
}
1
Watermamal 31 जिंदा 2020, 19:53

मेरे पास यह बहुत ही क्रूड टेस्ट काम कर रहा है। एक शीट प्रस्तुत की जाती है और जब आप स्वाइप करते हैं, तो ऑन डिसएपियर चालू हो जाता है और doExit फ़ंक्शन निष्पादित करता है। UIHostingController के बारे में कुछ नहीं जानते।

struct ContentView: View {
@State var testArray = ["one", "two", "three"]
@State var showMe = false

var body: some View {
    Button(action: { self.showMe = true}) {
        Text("Press button")
    }.sheet(isPresented: $showMe, onDismiss: {self.showMe = false}) { TestView(scheduleManager: self.testArray) }
}
}

struct TestView: View {
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@State var scheduleManager: [String]

var body: some View {
    NavigationView {
        Form {
            ForEach(scheduleManager, id: \.self) { timer in
                Text(timer)
            }
        }
    }.onDisappear(perform: doExit)
}

func doExit() {
    print("-----> TestView doExit")
    // then to go back to the previous view
    self.presentationMode.wrappedValue.dismiss()
}
}
0
workingdog 30 जिंदा 2020, 08:13

मैं जो अक्सर करता हूं वह कुछ ऐसा होता है:

struct ScheduleView: View {

@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

@ObservedObject var scheduleManager = ScheduleManager() 

var body: some View {
    NavigationView {
        Form {
            ForEach(scheduleManager.timers) { timer in
                ScheduleForm(scheduleManager: self.scheduleManager, timer: timer)
            }
        }
    }.onDisappear(perform: doExit)
     .navigationBarTitle(Text("Schedule"), displayMode: .inline)
}

func doExit() {

  // do your closing etc ... here

  // then to go back to the previous view
  self.presentationMode.wrappedValue.dismiss()
}

}

0
workingdog 30 जिंदा 2020, 06:33

सफलता और त्रुटि पूर्ण होने के लिए एकल क्लोजर का उपयोग करने के लिए मैंने जो पहली चीज की थी, वह आपके फ़ंक्शन हस्ताक्षर को बदल रही थी।

func sendMsg(_ message: String, completion: ((Bool) ->())? = nil)

फिर हम इसे ऑनडिसपीयर संशोधक के अंदर उपयोग कर सकते हैं। पूरा होने पर कनेक्शन बंद कर दें।

struct ContentView: View {

  var body: some View {

    Text("Hello World").onDisappear {
      sendMsg("last msg", completion: { completed in
        close()
      })
    }

  }
}
0
jnblanchard 30 जिंदा 2020, 02:50