Today Extension view flashes when redrawing
Asked Answered
W

2

13

According to Apple documentation, "To help your widget look up to date, the system occasionally captures snapshots of your widget’s view. When the widget becomes visible again, the most recent snapshot is displayed until the system replaces it with a live version of the view."

What I am seeing, however, is that the snapshot is removed from screen before the live view is prepared. This results in a flash effect where the old snapshot is taken off screen, the view is blank for a split second, then the new view appears.

Is the developer responsible for making the transition between the snapshot and the live view seamless? If so, what is the strategy behind doing that? I don't see any way to directly control that transition.

I was able to mitigate the effect greatly by moving data loading to widgetPerformUpdateWithCompletionHandler: and keeping drawing in viewWillAppear:, but I do still see a flash once every 15 (or so) opens of the Notification Center.

Weissberg answered 23/10, 2014 at 7:48 Comment(0)
S
27

I had this same issue and finally figured out the issue I was having with my widget. It turns out it was related to a misunderstanding about the Widget Life Cycle on my behalf.

From the documentation I thought that the today view would keep a 'snapshot' of my widgets state until the widgetPerformUpdateWithCompletionHandler method completion handler was called with success.

This does not seem to be the case. From what I can see the 'snapshot' is just used when the Today View is animating in (when the user pulls down the notification centre). As soon as the today view is loaded and stationary your widget is loaded from scratch (inflated from xib if using) and viewDidLoad is called. At this moment you should populate you widget with cached data (not from a web request). If you don't you will see temporary data from your nib. This is what causes the flashing.

When viewDidLoad is complete widgetPerformUpdateWithCompletionHandler is called which allows you to fetch fresh data. When the fresh data is fetched you should call the completion handler and cache the data it so it can be used when the widget is loaded later on from scratch (in viewDidLoad).

A simple way to cache the data is in user defaults.

Shumpert answered 20/2, 2015 at 22:53 Comment(5)
Well, your misunderstanding of the "snapshot" is exactly equivalent to my own misunderstanding of the snapshot, it would seem. Thanks for your research and input. I'll give it a shot and let you know if it solves my flash problem (I suspect it will, given what you've described).Weissberg
@Weissberg Did this work for you? If so, remember to mark it as the correct answer to help others :)Shumpert
Haven't had an opportunity to try this out yet. Honestly, the Today Widget has become almost the lowest priority for our project these days. If I can find some time to try this out next week, I will do so so I can mark a correct answer.Weissberg
Confirming this solves the flickering issue. Caching the data and restoring it in viewDidLoad avoids flickering. I used to restore the data in widgetPerformUpdateWithCompletionHandler and constantly had this flickering. Thanks @bencallis!Cida
Also note that widgetPerformUpdateWithCompletionHandler is called only after viewDidLoad and at "opportune times" as per Apple doc. This means if you are updating your data in the viewDidLoad or widgetPerformUpdateWithCompletionHandler and if the user pulls down the notification center the second time and you have data to update then it will not necessarily be updated in the widget. I used viewWillAppear to update the data.Audryaudrye
D
2

You need to be careful about your compilation handler in the

-(void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult))completionHandler

method. What happens is that your extension probably has an error and everytime view appers it is being called again. Try to attach your extension to debugger(Debugger->Attach to Process-> your extension id) and see the result by putting some breakpoints.

Demosthenes answered 23/10, 2014 at 8:9 Comment(3)
Yes, I have done extensive logging and breakpoint watching on this issue. If I place a breakpoint at the very beginning of widgetPerformUpdateWithCompletionHandler: and wait a moment, the widget content completely disappears. This is before any data loading or UI layout or anything. It is true that widgetPerformUpdateWithCompletionHandler: is being called every time the view appears, but that seems consistent with 8.1 documentation. What is not clear is which view controller methods are called in what order and at what times for widgets. They do not behave like typical view controllers.Weissberg
They actually behave if you have no errors. I don't know anything about your code but there is and error which causes it to crash that's why your view disappear. Please look into device system log to find the issue.Demosthenes
Well, I see nothing in the crash logs. But I'll continue along with your advice and see if there is some other error that we haven't detected yet.Weissberg

© 2022 - 2024 — McMap. All rights reserved.