MonoTouch 中自定义 TabBarController 中的 ViewDidLoad 中的公共属性始终为 null

发布于 2024-11-30 23:51:37 字数 2261 浏览 1 评论 0原文

我一直在研究从 UITabBarController 派生的类。在最基本的层面上,我想做的是添加一个 BackgroundColor 属性和其他公共属性,当我构建 TabBarController 时,我可以在 AppDelegate 中实例化它们。

我遇到的问题是,我可以在调用 ViewDidLoad 时让所有公共属性最终为 null,或者,我可以添加构造函数和 [Register] 属性,最终属性不为 null,但 ViewControllers属性(包含所有选项卡)变得莫名其妙地为空(即使您在 ViewDidLoad 中设置它)。

显然,我需要这两件事都是真实的,但我错过了一些具体的东西。

这是代码的版本,即使我在 AppDelegate 中显式设置它,它也始终会导致 null BackgroundColor:

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 };
    }
}

这是编辑后的代码,显示正确的背景颜色(该属性不为 null),但拒绝允许 ViewControllers 属性除了 null 之外的任何内容,即使它只是在 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 = BackgroundColor;
            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");
        }
    }
}

如果我必须显式添加所有元素而无法在运行时访问公共属性,这显然会阻碍我编写一些自定义控件的能力。有谁知道我哪里出错了?

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 = BackgroundColor;
            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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

写给空气的情书 2024-12-07 23:51:37

在调用 ViewDidLoad 之前必须发生一些事情。它们可以在构造函数中完成。然而,以下 ctor 是不好的:

 public TabBarController() : base(NSObjectFlag.Empty)

因为它不允许 UITabController 默认 ctor 执行 - 它的工作是向“init”选择器发送消息。

我认为你想要的看起来有点像:

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;
... 

编辑:删除了.ctor中的无操作背景设置。添加 FinishedLaunching 示例代码。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文