开发者

Public properties are always null in ViewDidLoad in a custom TabBarController in MonoTouch

开发者 https://www.devze.com 2023-03-29 22:10 出处:网络
I\'ve been working on a class derived from UITabBarController. At the most basic level, what I\'m trying to do is add a BackgroundColor property, and other public properties, that I can instantiate in

I've been working on a class derived from UITabBarController. At the most basic level, what I'm trying to do is add a BackgroundColor property, and other public properties, that I can instantiate in my AppDelegate when I'm constructing my TabBarController.

The problem I've run into is, I can either have all public properties end up being null when ViewDidLoad is called, or, I can add a constructor and a [Register] attribute, and end up having properties not null, but the ViewControllers property (which contains all tabs) becomes inexplicably null (even when you set it in ViewDidLoad).

Obviously, I need both things to be true and I'm missing something specific.

Here is the version of the code that always results in a null BackgroundColor, even if I set it explicitly in AppDelegate:

public class TabBarController : UITabBarController
{
    public UIColor BackgroundColor { get; set; }

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

        if(BackgroundColor != null) // Always null, even when set explicitly
        {
            var frame = new RectangleF(0.0f, 0.0f, this.View.Bounds.Size.Width, 46);
            UIView myTabView = new UIView(frame);
            myTabView.BackgroundColor = BackgroundColor;
            myTabView.Alpha = 0.5f;
            this.TabBar.InsertSubview(myTabView, 0);
        }

        // Add tabs here, which show up correctly (on default background color)
        ViewControllers = new UIViewController[] { one, two, three, etc };
    }
}

Here is the edited code that shows the correct background color (the property is not null), but refuses to allow ViewControllers property be anything but null, even when it is just set in ViewDidLoad:

[Register("TabBarController")]
public class TabBarController : UITabBarController
{
    public UIColor BackgroundColor { get; set; }

    // Added a binding constructor
    [Export("init")]
    public TabBarController() : base(NSObjectFlag.Empty)
    {

    }

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

        if(BackgroundColor != null) // Hey, this works now!
        {
            var frame = new RectangleF(0.0f, 0.0f, this.View.Bounds.Size.Width, 46);
            UIView myTabView = new UIView(frame);
            myTabView.BackgroundColor = Bac开发者_运维百科kgroundColor;
            myTabView.Alpha = 0.5f;
            this.TabBar.InsertSubview(myTabView, 0);
        }

        // Tabs disappear, ViewControllers is always null
        ViewControllers = new UIViewController[] { one, two, three, etc };
        if(ViewControllers == null)
        {
            Console.WriteLine("Not bro");
        }
    }
}

This obviously deters my ability to write some custom controls if I have to explicitly add all elements without being able to access public properties at runtime. Does anyone know where I'm going wrong?


There are things that must occurs before ViewDidLoad is called. They can be done in the constructor. However the following ctor is bad:

 public TabBarController() : base(NSObjectFlag.Empty)

because it won't allow UITabController default ctor to execute - and its job is to send a message to the 'init' selector.

I think what you want looks a bit like:

public class TabBarController : UITabBarController
{
    UIViewController one = new UIViewController ();
    UIViewController two = new UIViewController ();
    UIViewController three = new UIViewController ();

    private UIView myTabView;

    public UIColor BackgroundColor { 
        get { return myTabView.BackgroundColor; }
        set { myTabView.BackgroundColor = value; }
    }       

    public TabBarController()
    {
        var frame = new RectangleF(0.0f, 0.0f, this.View.Bounds.Size.Width, 46);
        myTabView = new UIView(frame);
        myTabView.Alpha = 0.5f;
        this.TabBar.InsertSubview(myTabView, 0);

        // Add tabs here, which show up correctly (on default background color)
        ViewControllers = new UIViewController[] { one, two, three };
    }
}

    public override bool FinishedLaunching (UIApplication app, NSDictionary options)
    {
        TabBarController controller = new TabBarController ();
        // change background (to cyan) works before adding subview
        controller.BackgroundColor = UIColor.Cyan;
        window.AddSubview (controller.View);
        // change background (to blue) works after adding subview
        controller.BackgroundColor = UIColor.Blue;
... 

EDIT: Removed no-op background setting in .ctor. Added FinishedLaunching sample code.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号