最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

swift - SwiftUI won't call delegates if a task is spawned? - Stack Overflow

programmeradmin2浏览0评论

Created a demo application to showcase this issue here

  • macOS 15.2 (24C101)
  • Xcode 16.2 (16C5032a)
  • Hardware MacBook Pro Apple M4
struct ContentView: View {
    @Binding var document: didchangeDocument
    
    @State var task: Task<Void, Never>?

    var body: some View {
        TestView()
            .onAppear {
                self.task = Task { }
            }
    }
}

While self.task = Task { } exists none of the following fire just looking for an explination as to why? Comment it out to fix it. This happens regardless of what ones are enabled and breaks all delegate call backs no all sub views.

  • NSTextDelegate.textDidChange(_:)
  • NSTextContentStorageDelegate.textContentStorage(_:textParagraphWith:)
  • NSTextLayoutManagerDelegate.textLayoutManager(_:textLayoutFragmentFor:in:)
  • NSTextStorageDelegate.textStorage(_:didProcessEditing:range:changeInLength:)

What I have been able to determin is there are a couple conditions required to break it.

  1. You must have a FileDocument bound to your view if you just have a bound @State String it doesn't seem to be affected.
  2. You must create an attach a Task as a @State

Was trying to debounce the @Binding update via onChange when I noticed this as it worked before I used a delegate to do the update and regular TextView didn't seem to be affected.

I found a different way to debounce this with a @StateObject that works so my main curiosity is just why this happens ans what is going on. With the annotations of @State @Binding and SwiftUI in general a lot of the inner workings are hidden from me and I want to know what is causing this issue so I can avoid other issues like it in the future and better understand what is going on under the hood. I haven't found any information on this specifically. If there is something similar I would also like to know about that.

Created a demo application to showcase this issue here https://github.com/BrandonRoehl/didchange

  • macOS 15.2 (24C101)
  • Xcode 16.2 (16C5032a)
  • Hardware MacBook Pro Apple M4
struct ContentView: View {
    @Binding var document: didchangeDocument
    
    @State var task: Task<Void, Never>?

    var body: some View {
        TestView()
            .onAppear {
                self.task = Task { }
            }
    }
}

While self.task = Task { } exists none of the following fire just looking for an explination as to why? Comment it out to fix it. This happens regardless of what ones are enabled and breaks all delegate call backs no all sub views.

  • NSTextDelegate.textDidChange(_:)
  • NSTextContentStorageDelegate.textContentStorage(_:textParagraphWith:)
  • NSTextLayoutManagerDelegate.textLayoutManager(_:textLayoutFragmentFor:in:)
  • NSTextStorageDelegate.textStorage(_:didProcessEditing:range:changeInLength:)

What I have been able to determin is there are a couple conditions required to break it.

  1. You must have a FileDocument bound to your view if you just have a bound @State String it doesn't seem to be affected.
  2. You must create an attach a Task as a @State

Was trying to debounce the @Binding update via onChange when I noticed this as it worked before I used a delegate to do the update and regular TextView didn't seem to be affected.

I found a different way to debounce this with a @StateObject that works so my main curiosity is just why this happens ans what is going on. With the annotations of @State @Binding and SwiftUI in general a lot of the inner workings are hidden from me and I want to know what is causing this issue so I can avoid other issues like it in the future and better understand what is going on under the hood. I haven't found any information on this specifically. If there is something similar I would also like to know about that.

Share Improve this question asked Jan 19 at 3:14 Brandon RoehlBrandon Roehl 236 bronze badges 0
Add a comment  | 

1 Answer 1

Reset to default 0

For the next person that sees this the issue is right here.

https://github.com/BrandonRoehl/didchange/blob/main/didchange/TestView.swift#L50

The text view is re-initilized when a Coordinator needs to be set for the state and hold the delegates that need to fix it. https://github.com/BrandonRoehl/didchange/commit/1a9a111c0063c633604a982683a99c9ff476fe63

changing

let delegate = TestDelegate()

into

public func makeCoordinator() -> TestDelegate {
    return TestDelegate()
}

sad to admit how many days this took to figure out but hope this helps someone else

发布评论

评论列表(0)

  1. 暂无评论