Search code examples
iosxamarinxamarin.iosios11today-extension

Almost all time cannot show more for Xamarin Today widget on iOS 11


I have today widget and sometimes "show more" is not working. This issue appears only in iOS 11, previous versions (8, 9, 10) worked well. I don't understand what I'm doing wrong and why I cannot make widget expanded. I've investigate this issue and found that "WidgetPerformUpdate" was not triggered after change "PreferredContentSize" inside "WidgetActiveDisplayModeDidChange" and this is beacause "View.Bounds" of widget not changed after changing "PreferredContentSize".

Here is my sample of code:

[Register ("TodayViewController")]
public class TodayViewController : UIViewController, INCWidgetProviding
{
    private const int PreferredHeight = 300;

    private readonly ISettings _settings;

    public TodayViewController(IntPtr handle) : base (handle)
    {
        _settings = AppContainer.Resolve<ISettings>();
    }

    static TodayViewController()
    {
        AppContainer.Container = (new iOSAppSetup()).CreateContainer();
    }

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();

        AddOpenApplicationEvent();

        // Tell widget it can be expanded
                ExtensionContext.SetWidgetLargestAvailableDisplayMode(NCWidgetDisplayMode.Expanded);

        // Get the maximum size
        var maxSize = ExtensionContext.GetWidgetMaximumSize(NCWidgetDisplayMode.Expanded);
        PreferredContentSize = new CGSize(maxSize.Width, PreferredHeight);

        View.AddSubview(***view according to maxSize***);
    }

    private void AddOpenApplicationEvent()
    {
        var tapWidget = new UITapGestureRecognizer();
        tapWidget.AddTarget(() =>
        {
            UIApplication.SharedApplication.OpenUrl(new NSUrl("test://"));
        });

        View.AddGestureRecognizer(tapWidget);
    }

    [Export("widgetPerformUpdateWithCompletionHandler:")]
    public void WidgetPerformUpdate(Action<NCUpdateResult> completionHandler)
    {
        UpdateWidget();

        switch (ExtensionContext.GetWidgetActiveDisplayMode())
        {
            case NCWidgetDisplayMode.Compact:
                // changes according to compact mode
                break;
            case NCWidgetDisplayMode.Expanded:
                // changes according to expanded mode
                break;
        }

        completionHandler(NCUpdateResult.NewData);
    }

    [Export("widgetActiveDisplayModeDidChange:withMaximumSize:")]
    public void WidgetActiveDisplayModeDidChange(NCWidgetDisplayMode activeDisplayMode, CGSize maxSize)
    {
        // Take action based on the display mode
        switch (activeDisplayMode)
        {
            case NCWidgetDisplayMode.Compact:
                PreferredContentSize = maxSize;
                // changes according to compact mode
                break;
            case NCWidgetDisplayMode.Expanded:
                PreferredContentSize = new CGSize(maxSize.Width, PreferredHeight);
                // changes according to expanded mode
                break;
        }
    }

    private void UpdateWidget()
    {
        // some updates
    }

P.S. sometimes it working after navigation to the app through widget.


Solution

  • In iOS-11 also, Show More/Show Less is working fine.

    I have created a basic sample to describe this:

    class TodayViewController: UIViewController, NCWidgetProviding
    {
        override func viewDidLoad()
        {
            super.viewDidLoad()
            self.extensionContext?.widgetLargestAvailableDisplayMode = .expanded
        }
    
        func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void))
        {
            completionHandler(NCUpdateResult.newData)
        }
    
        func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize)
        {
            if activeDisplayMode == .expanded
            {
                preferredContentSize = CGSize(width: 0.0, height: 300.0)
            }
            else
            {
                preferredContentSize = maxSize
            }
        }
    }