Skip to content
This repository has been archived by the owner on May 1, 2024. It is now read-only.

Fix crash creating native image of size 0,0 #15828

Closed
wants to merge 1 commit into from

Conversation

taublast
Copy link

@taublast taublast commented Oct 13, 2023

Fixes bug appeared on iOS 17 crash creating native image of zero size when linear gradient is set for button at app startup

Description of Change

  • iOS

Behavioral/Visual Changes

No crash

Before/After Screenshots

on iOS 17 crash creating native image of zero size when linear gradient is set for button at app startup

Fixes bug appeared on iOS 17 crash creating native image of zero size when linear gradient is set for button at app startup
@SnowPowerCore
Copy link

SnowPowerCore commented Oct 17, 2023

+1 having this recent issue, would be really neat if this PR was merged

@taublast
Copy link
Author

meanwhile you can use a use a custom renderer that would call the fixed extension. here is one for a Button for example:

using CoreGraphics;
using CRMMobileApp.iOS;
using Foundation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

[assembly: ExportRenderer(typeof(Button), typeof(EnhancedButtonRenderer))]
namespace XXX.iOS
{
    public class EnhancedButtonRenderer : ButtonRenderer
    {
        //FIXED EXTENSION METHOD
        UIImage GetMyBackgroundImage(UIView control, Brush brush)
        {
            if (control == null || brush == null || brush.IsEmpty || control.Bounds == CGRect.Empty)
                return null;

            var backgroundLayer = control.GetBackgroundLayer(brush);

            if (backgroundLayer == null)
                return null;

            UIGraphics.BeginImageContextWithOptions(backgroundLayer.Bounds.Size, false, UIScreen.MainScreen.Scale);

            if (UIGraphics.GetCurrentContext() == null)
                return null;

            backgroundLayer.RenderInContext(UIGraphics.GetCurrentContext());
            UIImage gradientImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();

            return gradientImage;
        }

        protected override void SetBackground(Brush brush)
        {
            if (Control == null)
                return;

            try
            {
                UIColor backgroundColor = Element.BackgroundColor == Color.Default ? null : Element.BackgroundColor.ToUIColor();

                if (!Brush.IsNullOrEmpty(brush))
                {
                    if (brush is SolidColorBrush solidColorBrush)
                        backgroundColor = solidColorBrush.Color.ToUIColor();
                    else
                    {
                        //CALLING FIXED EXTENSION METHOD
                        var backgroundImage = GetMyBackgroundImage(this, brush);
                        backgroundColor = backgroundImage != null ? UIColor.FromPatternImage(backgroundImage) : UIColor.Clear;
                    }
                }

                Control.BackgroundColor = backgroundColor;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

    }
}

@jfversluis
Copy link
Member

jfversluis commented Oct 23, 2023

/azp run

@azure-pipelines

This comment was marked as outdated.

@jfversluis
Copy link
Member

Thanks so much for taking this up @taublast!

@jfversluis jfversluis added the iOS 17 Issues/PRs that are specific to iOS 17/Xcode 15 label Oct 23, 2023
@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@damiannestle
Copy link

Unfortunately this isn't the only control impacted by this issue - I'm getting the same error rendering a BoxView

@campersau
Copy link
Contributor

@damiannestle you can simply copy the workaround for BoxView as well using the BoxRenderer instead.

@damiannestle
Copy link

damiannestle commented Nov 2, 2023

@damiannestle you can simply copy the workaround for BoxView as well using the BoxRenderer instead.

Yes I've done that, although it is not quite so simple - the SetBackground method in BoxRenderer (which calls GetBackgroundImage which is the cause of the issue) accesses private members (_colorToRenderer) so I had to create a renderer that derived from VisualElementRenderer<BoxView> and copy the code from BoxRenderer, modified to call a local GetBackgroundImage per the above code.

If there is a simpler way I'd be happy to update my code.

It should really be fixed by Microsoft in Xamarin.Forms.Platform.iOS.BrushExtensions.GetBackgroundImage

@jfversluis
Copy link
Member

jfversluis commented Nov 3, 2023

@damiannestle do you have some code or reproduction that shows this bug? Could you maybe open a new issue for it so we can track that better separately?

@jfversluis
Copy link
Member

Would anyone experiencing this be able to try the NuGets that result from this PR (see instructions here) and let me know if that fixes it for you?

@albilaga
Copy link

albilaga commented Nov 9, 2023

Would anyone experiencing this be able to try the NuGets that result from this PR (see instructions here) and let me know if that fixes it for you?

tried this and it working for my project. Is there will be another release for this @jfversluis ?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
iOS 17 Issues/PRs that are specific to iOS 17/Xcode 15
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants