Change NCWidgetDisplayMode programmatically in IOS

2019-04-10 00:14发布

问题:

I am looking to programmatically change the height of a today extension. As the iOS10 SDSK introduced NCWidgetDisplayMode I am trying to use it to programmatically change the height of my preferredContentSize.

I have implemented widgetActiveDisplayModeDidChange:

@available(iOSApplicationExtension 10.0, *)
func widgetActiveDisplayModeDidChange(activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
    if (activeDisplayMode == NCWidgetDisplayMode.Compact) {
        self.preferredContentSize = maxSize
    }
    else {
        self.preferredContentSize = CGSize(width: maxSize.width, height: 280)
    }
}

I want the widget height to expand when a UIButton is pressed :

@IBAction func multiplybyonethousand (sender: AnyObject) {

    if self.extensionContext?.widgetActiveDisplayMode == NCWidgetDisplayMode.Compact {

        self.widgetActiveDisplayModeDidChange(.Expanded, withMaximumSize: CGSizeMake(0, 300))
    }
}

However when I run my code, the height of the today extension does not change and the console gives me the following error:

2016-11-05 14:24:29.425697 todayextension[28590:7222420] No active animation block!

I have tried to call widgetActiveDisplayModeDidChange inside an animation block:

@IBAction func multiplybyonethousand (sender: AnyObject) {
        if self.extensionContext?.widgetActiveDisplayMode == NCWidgetDisplayMode.Compact {
            UIView.animateWithDuration(0.2, delay: 0, options: .CurveLinear, animations: { () -> Void in
                self.widgetActiveDisplayModeDidChange(.Expanded, withMaximumSize: CGSizeMake(0, 300))

            }) { (completed) -> Void in
             //Do Stuff
            }
        }
}

But I still get the No active animation block! error message. Is there a way to programmatically expand a today extension view in iOS10 ?

回答1:

In iOS 10, Show More/Show Less button is automatically provided in the Today's Extension. So height of the widget is handled automatically through NCWidgetDisplayMode. You don't need to provide any explicit button for handling the widget's height.

override func viewDidLoad() {
    super.viewDidLoad()

    if #available(iOSApplicationExtension 10.0, *) {
        self.extensionContext?.widgetLargestAvailableDisplayMode = .expanded
    }
}

Implement NCWidgetProviding protocol's method:

@available(iOSApplicationExtension 10.0, *)
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
    if activeDisplayMode == .expanded {
            preferredContentSize = CGSize(width: maxSize.width, height: 300)
    } else {
        preferredContentSize = maxSize
    }
}

In, iOS 8 and iOS 9, you need to explicitly handle widget's height. In iOS 10, it is not required.

You can refer to https://github.com/pgpt10/Today-Widget on Today's Widget implementation in iOS 8, iOS 9 and iOS 10.