How to hide the iOS 8 Today Widget when there is nothing to display?
Asked Answered
D

4

6

I'm using the today widget for iOS8 to display information relevant to the current day. The problem is I don't want to display the widget/section at all if there are no relevant messages to show.

I know it must be possible as the BA app does it (it only shows the widget when there is a flight, the rest of the time its not visible at all). I just cant figure out a way to achieve this behaviour.

Does anyone know how this can be done?

Debroahdebs answered 26/9, 2014 at 19:38 Comment(0)
D
15

I found the way to do this is using the NCWidgetController. This allows you to easily specify when the today widget should be displayed based on whatever criteria you see fit.

Simply add the following into your viewDidLoad method (or anywhere that will be called when the widget reloads) in the today widget view controller and it will work:

BOOL hasDataToDisplay = NO;

NCWidgetController *widgetController = [NCWidgetController widgetController];
[widgetController setHasContent:hasDataToDisplay forWidgetWithBundleIdentifier:@"com.my-company.my-app.my-widget"];

Apple Docs: https://developer.apple.com/library/ios/documentation/NotificationCenter/Reference/NCWidgetController_Class/index.html#//apple_ref/occ/cl/NCWidgetController

WARNING: The NCWidgetController cannot be reset from the widget itself once you have set there is no content to display. In other words once you set it to NO then there is no going back unless you trigger it from the parent/containing app.

Debroahdebs answered 27/9, 2014 at 20:10 Comment(1)
hi, tahnks for the super answer, but question please for this note: "The NCWidgetController cannot be reset from the widget itself once you have set there is no content to display. In other words once you set it to NO then there is no going back unless you trigger it from the parent/containing app." how can I "trigger it from the parent/containing app." I didn't got you very well, can you give me example? thanks so mushCusco
I
4

In the widget's ViewController's viewDidLoad method add the following:

BOOL DisplayWidget = NO;
[[NCWidgetController widgetController] setHasContent:DisplayWidget 
                       forWidgetWithBundleIdentifier:@"<widget's bunder identifier>"];

This will disable the widget from showing.

To enable it again, you must do that from the containing app using the same line passing YES to setHasContent parameter. Make sure to add the necessary imports to the containing app in the ViewController which will re-enable the widget:

#import <NotificationCenter/NotificationCenter.h>

@interface ViewController () <NCWidgetProviding> {...}

[Check out page 41 of the documentations for widgets https://developer.apple.com/library/ios/documentation/General/Conceptual/ExtensibilityPG/ExtensibilityPG.pdf ]

Ithunn answered 17/5, 2015 at 18:43 Comment(0)
N
0

The approach which I used, though not perfect and has a small remnant in Notification Center, but worked for me:

In viewDidLoad() set preferred content size height to 1:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view from its nib.
    preferredContentSize = CGSizeMake(0, 1)
    view.setNeedsLayout()
}

then when widget updates, gets real height and set it:

var data: NSData?

func updateData() {
    // fetch data
    if let data = data {
        let viewHeight: CGFloat
        // UI preperation and initialize viewHeight var
        preferredContentSize = CGSizeMake(0, viewHeight);
    } else {
        preferredContentSize = CGSizeMake(0, 1);
    }

}

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) {
    // Perform any setup necessary in order to update the view.

    // If an error is encountered, use NCUpdateResult.Failed
    // If there's no update required, use NCUpdateResult.NoData
    // If there's an update, use NCUpdateResult.NewData

    updateData()

    completionHandler(data != nil ? NCUpdateResult.NewData : NCUpdateResult.NoData)
}
Nate answered 12/9, 2015 at 12:7 Comment(0)
A
-1

It is better use

+ (instancetype)widgetController

then call

- (void)setHasContent:(BOOL)flag forWidgetWithBundleIdentifier:(NSString *)bundleID
Ashy answered 5/12, 2014 at 15:20 Comment(2)
Why do you think that's better?Molehill
@defense2000x because that is documented at developer.apple.com/library/ios/documentation/…Misreckon

© 2022 - 2024 — McMap. All rights reserved.