Xamarin子类化UINavigationController和自定义UINavigationBar

本文关键字:自定义 UINavigationBar UINavigationController 子类 Xamarin | 更新日期: 2023-09-27 18:16:55

我正在尝试创建一个非标准的顶部导航栏用于整个应用程序。为了实现这一点,我一直在尝试子类UINavigationControllerUINavigationBar

我有一个自定义NavigationController

partial class ZooNavigationController : UINavigationController
{
    public ZooNavigationController (IntPtr handle) : base (typeof(TopNavBar), null)
    {
        this.Handle = handle;
    }
}

,指向基构造函数

public UINavigationController (Type navigationBarType, Type toolbarType); 

为我的自定义UINavigationBarTopNavBar,这是类似于…

public class TopNavBar : UINavigationBar
{
    public TopNavBar ()
    {
        InitCustom ();
    }
    public void InitCustom(){ 
        this.BackgroundColor = UIColor.Red; 
        // a bunch more custom stuff
    }
}

问题是,TopNavBar从来没有被调用当我运行这个。如果我试着把构造函数调整成这样:

    public ZooNavigationController (IntPtr handle) : base (typeof(TopNavBar), null)
    {
        this.Handle = handle;
        TopNavBar test = (TopNavBar)this.NavigationBar;
    }

我得到一个运行时异常,它不能转换类型,所以它似乎忽略了我指定UINavigationBar类型的调用。

有谁能帮我解释一下我遗漏了什么吗?

EDIT最后我发现我忽略了你可以在故事板中设置自定义UINavigationBar的事实。结合miguel的回答,我最终得到了类

partial class TopNavBar : UINavigationBar
{
    public TopNavBar(IntPtr test) : base(test) {
    }
    [Export ("initWithCoder:")]
    public TopNavBar (NSCoder coder) : base (coder)  {
        InitCustom ();
    }
}

Xamarin子类化UINavigationController和自定义UINavigationBar

IntPtr构造函数是为了响应Objective-C创建的对象而调用的,并在c#中出现。这通常不是这些类实例化的方式。

你要问自己的第一个问题是:谁在创建你的类的实例?
  • 你从c#中创建这个类的实例:你用适当的参数调用构造函数。
  • 在反序列化期间创建(例如,从故事板,XIB或您自己的存档数据加载),那么您需要提供接受NSCoder参数的构造函数。
  • 根据需要重新创建实例(可能表明有问题,因为这意味着你的对象被销毁,但是Objective-C保留了对它的引用,现在它又重新出现了),IntPtr构造函数。
在上面的例子中,有一个错误:你重写了IntPtr构造函数,它应该只调用基类IntPtr构造函数(因为它意味着"我有一个指向objective-c中实际对象的指针,为它创建一个包装器")。

我的猜测是你正在使用c#,所以在这种情况下,你想要的是提供一个新的构造函数,不接受参数:

public ZooNavigationController () : base (typeof (YourNavigation), typeof(YourBar)) {
   // Your own initialization goes here
}