TextureGroup / Texture

Smooth asynchronous user interfaces for iOS apps.
https://texturegroup.org/
Other
8.02k stars 1.29k forks source link

Cannot update ui by calling setneedslayout immediately after the node initialised in 2.7 #964

Open fans3210 opened 6 years ago

fans3210 commented 6 years ago

I have a chat app implemented in asyncdisplaykit, and the last version I used was 2.5.1. I have a image upload usecase which is shown in the video below:

https://asyncdisplaykit.slack.com/files/U4HRU63CH/FB07PTMHN/screenrecording_06-04-2018_14-42-41.mp4

Or this:

https://www.dropbox.com/s/ei9r5uo1wegunaj/screenrecording_06-04-2018_14-42-41.mp4?dl=0

Everything worked well until I upgraded to 2.7:

https://asyncdisplaykit.slack.com/files/U4HRU63CH/FB0ML27C4/screenrecording_06-04-2018_14-47-00.mp4

Or this:

https://www.dropbox.com/s/9i55m7gw6121hj0/screenrecording_06-04-2018_14-47-00.mp4?dl=0

You can see from the video that the bubble became empty when I nav back and in. I'm using an rxswift observer to observe a global file upload state and will update the ui immediately in didEnterVisibleState function like below:

    override func didEnterVisibleState() {
        super.didEnterVisibleState()

        setupObservables() //will update ui in main thread
    }

    override func didExitVisibleState() {
        super.didExitVisibleState()
        tearDownObservables()

        //reset the progress state in case the finished uploading lost track
        resetUI()
    }

the 'setupobservables' include logics of updating the ui with the observed uploading progress value

Tried printout the layout and didn't find anything wrong, I'm setting automanagedsubnodes to true

Now what I figured out why the ui progress bar displayed correctly at first but got prob when I nav back and nav in again. I think there is a small delay in the new version between the layout finished and didEnterVisibleState time window, I have to manually add a small delay or async dispatch or aysnc dispatch to make the ui display correctly like below:

                DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                    self.setProgress(CGFloat(progress), with: "uploading")
                }

Or

                DispatchQueue.main.async {
                    self.setProgress(CGFloat(progress), with: "uploading")
                }

But the blank ui issue is not related to threading because I always call the update ui function in main thread controlled by rxswift.

Previously in 2.5.1 I don't need to add such delay. No luck asking in slack. Would be very appreciated if you could provide some help!

GeekTree0101 commented 6 years ago

Me too, I faced this issue. In my case, I forced setNeedLayout after textNode attributedText value with a few sec delay


     Observable.just(NSAttributedString(string: "test")
            .delay(2.0, scheduler: MainScheduler.asyncInstance) // a few sec delay
            .subscribe(onNext: { [weak self] value in 
                    self?.textNode.attributedText = value // update attributedText (data)
                    self?.setNeedsLayout()  // call setNeedsLayout
             }
            .disposed(by: disposeBag)

Texture v2.6 doesn't have problem

v2 6

but, In same code, Texture v2.7 occur problem like this picture

v2 7
4faramita commented 6 years ago

Same problem here.

In my case, I implemented didSelectRowAt in ASTableNode to present another VC. After tap, the didSelectRowAt emits immediately while the viewWillAppear won't emit without a delay or a second tap.

Currently hacked using DispatchQueue.main.async manually.

fans3210 commented 6 years ago

I updated dropbox links for the videos