Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the "if (Control == null)" section used for in a Xamarin iOS renderer?

Looking at an example snippet from Xamarin, I saw that they suggest creating a custom renderer with three sections:

  1. if (Control == null)

  2. if (e.OldElement != null)

  3. if (e.NewElement != null)

My renderer looks like this. However, I do not understand what I would use the if (Control == null) section for.

Question 1) Can anyone give me advice on how this would be used, and also if there's anything wrong with my implementation?

Question 2) Am I implementing this correctly, and how/where should I remove the OnTabbarControllerItemSelected handler?

Question 3) Where does the Control element come from? Would that be the same variable that I have called _page or the element e?

tabbarController.ViewControllerSelected += OnTabbarControllerItemSelected;

public class TabbedPageRenderer : TabbedRenderer
{
    private MainPage _page;

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        //if (Control == null)
        //{
        //    // Instantiate the native control
        //}

        if (e.OldElement != null)
        {
            // Unsubscribe from event handlers and cleanup any resources
            e.OldElement.PropertyChanged -= Current_PropertyChanged;
            return;
        }

        if (e.NewElement != null)
        {
            // Configure the control and subscribe to event handlers
            TabBar.Translucent = false;
            TabBar.BackgroundImage = new UIImage();
            _page = (MainPage)e.NewElement;
            e.NewElement.PropertyChanged += Current_PropertyChanged;
        }

        try
        {
            var tabbarController = (UITabBarController)this.ViewController;
            if (tabbarController != null)
            {
                tabbarController.ViewControllerSelected += OnTabbarControllerItemSelected;
                UpdateTheme();
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }

    private void OnTabbarControllerItemSelected(object sender, UITabBarSelectionEventArgs eventArgs)
    {
        if (!(_page.CurrentPage is Japanese.CardsTabPage) && App.quizRunning == true)
            _page.CurrentPage = App.navCardsTabPage;
    }

    void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Theme")
            UpdateTheme();
    }

    void UpdateTheme()
    {
        switch (_page.Theme)
        {
            default:
            case TH.Light:
                TabBar.SelectedImageTintColor = UIColor.Red;
                break;
            case TH.Dark: 
                TabBar.SelectedImageTintColor = UIColor.Red;
                break;
        }
    }

}
like image 563
Alan2 Avatar asked Oct 25 '25 00:10

Alan2


1 Answers

Question 1 & 3

The snippet is for writing custom renderers, the Control property is in ViewRenderer class. Since your control inherits from TabbedRenderer, it's not necessary to follow the snippet.

Question 2

ViewController property returns the TabbedRenderer itself, so you don't need to add the listener every time OnElementChanged invoked. Consider move it to the constructor.

Like this:

public class TabbedPageRenderer : TabbedRenderer
{
    private MainPage _page;

    public TabbedPageRenderer()
    {
        this.ViewControllerSelected += OnTabbarControllerItemSelected;
    }

    protected override void OnElementChanged(VisualElementChangedEventArgs e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Unsubscribe from event handlers and cleanup any resources
            e.OldElement.PropertyChanged -= Current_PropertyChanged;
            return;
        }

        if (e.NewElement != null)
        {
            // Configure the control and subscribe to event handlers
            TabBar.Translucent = false;
            TabBar.BackgroundImage = new UIImage();
            _page = (MainPage)e.NewElement;
            e.NewElement.PropertyChanged += Current_PropertyChanged;
        }

        if(_page != null)
            UpdateTheme();
    }

    private void OnTabbarControllerItemSelected(object sender, UITabBarSelectionEventArgs eventArgs)
    {
        if (_page != null && !(_page.CurrentPage is Japanese.CardsTabPage) && App.quizRunning == true)
            _page.CurrentPage = App.navCardsTabPage;
    }

    void Current_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "Theme")
            UpdateTheme();
    }

    void UpdateTheme()
    {
        switch (_page.Theme)
        {
            default:
            case TH.Light:
                TabBar.SelectedImageTintColor = UIColor.Red;
                break;
            case TH.Dark: 
                TabBar.SelectedImageTintColor = UIColor.Red;
                break;
        }
    }
}
like image 193
shingo Avatar answered Oct 26 '25 15:10

shingo