0

I am trying to convert icons from type UIBarButtonSystemItem like UIBarButtonSystemItem.Camera into a UIImage. Users were able to do it in Swift and ObjC , but I'm not able to figure it out.

When I follow the instructions from Swift & ObjC tutorials, I am getting null reference exception errors in my code

{
    UIImage image = null;

    viewController.InvokeOnMainThread(() =>
    {
        UIBarButtonItem oldItem = viewController.NavigationItem.RightBarButtonItem;
        var buttonItem = new UIBarButtonItem(item);

        // Add to toolbar and render it
        viewController.NavigationItem.RightBarButtonItem = buttonItem;
        var x = new ObjCRuntime.Selector("view");
        var y = viewController.NavigationItem.RightBarButtonItem.PerformSelector(x);
        UIView itemView = (UIView)y;

        // Get the image from real UIButton
        foreach (var view in itemView.Subviews)
        {
            if (view.GetType() == typeof(UIButton))
                image = ((UIButton)view).ImageView.Image;
        }
                viewController.NavigationItem.RightBarButtonItem = oldItem;
    });

    return image;
}

And I tried this too,

public static UIImage ToUIImage2(UIBarButtonSystemItem item, UIViewController viewController)
{
    UIImage image = null;

    viewController.InvokeOnMainThread(() =>
    {
        var buttonItem = new UIBarButtonItem(item);
        // Add to toolbar and render it
        var tempItem = new UIBarButtonItem[1] { buttonItem };
        var bar = new UIToolbar();
        bar.SetItems(tempItem, false);
        bar.SnapshotView(true);

        // Get the image from real UIButton
        var buttonItemView = bar.ValueForKey(new Foundation.NSString("view"));
        var itemView = (UIView)buttonItemView;

        foreach (var view in itemView.Subviews)
        {
            if (view.GetType() == typeof(UIButton))
                image = ((UIButton)view).ImageView.Image;
        }
    });
    return image;
}

Can't find anything for C# in StackOverflow. Has anyone tried to do it before?

Saamer
  • 4,687
  • 1
  • 13
  • 55
  • 1
    "I am getting errors" - what errors are you getting? And please post the relevant code in the body, do NOT just link to offsite resources – Jason Feb 23 '19 at 00:03
  • Hey Jason! Thank you for your comments! I made updated my question based on your suggestion, I was getting a null reference exception in both cases – Saamer Feb 23 '19 at 00:15

1 Answers1

0
public extern static IntPtr IntPtr_objc_msgSend (IntPtr receiver, IntPtr selector);

public static UIImage GetImage (UIBarButtonSystemItem systemItem)
{
    var tempItem = new UIBarButtonItem (systemItem);

    // Add to toolbar and render it
    var bar = new UIToolbar ();
    bar.SetItems (new [] { tempItem }, false);
    bar.SnapshotView (true);

    // Get image from real UIButton
    var selHandle = Selector.GetHandle ("view");
    var itemView = Runtime.GetNSObject<UIView>(IntPtr_objc_msgSend (tempItem.Handle, selHandle));
    foreach    (var view in itemView?.Subviews) {
        if (view is UIButton button)
            return button.ImageForState (UIControlState.Normal);
    }

    return null;
}

Solution provided by @DaleXSoto from the Xamarin iOS Gitter

"The thing is that you are calling a selector (view) into the tempItem object but it is a hack since a UIBarButtonItem responds to view just because someone figured that out heh, it is not on the headers

So doing IntPtr_objc_msgSend is how you are calling view on tempItem object"

Saamer
  • 4,687
  • 1
  • 13
  • 55