2017-07-12 61 views
0

在我正在工作的应用程序中,需要定制UITableView节头和页脚。为此,我想创建一个可以与绑定和我们的逻辑结合使用的自定义控件。使用MvvmCross和XIB自定义UITableViewHeaderFooterView?

对于我创建了一个XIB并增加了支持类,看起来像下面这样:

public partial class HeaderFooterView : MvxTableViewHeaderFooterView 
{ 
    public static readonly NSString Key = new NSString("HeaderFooterView"); 
    public static readonly UINib Nib = UINib.FromName("HeaderFooterView", NSBundle.MainBundle); 

    public HeaderFooterView(IntPtr handle) : base(handle) 
    { 
    } 

    public override void AwakeFromNib() 
    { 
     base.AwakeFromNib(); 

     //var binding = this.CreateBindingSet<HeaderFooterView, TableViewSection>(); 


     //binding.Apply(); 
    } 
} 

MvxTableViewHeaderFooterView其实是一个相当简单的类,与IMvxBindable相结合的股票UITableViewHeaderFooterView。没有什么花哨。

但是出于某种原因,即使我把它注册到TableViewSource构造函数中正确:

tableView.RegisterNibForHeaderFooterViewReuse(HeaderFooterView.Nib, HeaderFooterView.Key); 

,做返回头本身只有正确的方法:

public override UIView GetViewForHeader(UITableView tableView, nint section) 
    { 
     return tableView.DequeueReusableHeaderFooterView(HeaderFooterView.Key); 
    } 

该应用程序与死亡出现以下错误:

2017-07-12 16:56:40.517 MyAppiOS[3833:58706] *** Assertion failure in -[UITableView _dequeueReusableViewOfType:withIdentifier:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UITableView.m:6696 
2017-07-12 16:56:40.528 MyAppiOS[3833:58706] WARNING: GoogleAnalytics 3.17 void GAIUncaughtExceptionHandler(NSException *) (GAIUncaughtExceptionHandler.m:48): Uncaught exception: invalid nib registered for identifier (HeaderFooterView) - nib must contain exactly one top level object which must be a UITableViewHeaderFooterView instance 

我的NIB实际上包含一个roo t对象,即根视图本身,该对象被设置为HeaderFooterView类(其源自MvxTableViewHeaderFooterView,其依次源自UITableViewHeaderFooterView)。但它声称没有UITableViewHeaderFooterView实例。

为什么它不能正常工作?

+0

我相信你必须为页脚/标题分配一个估计的高度,否则它将无法正确显示。 – Digitalsa1nt

+0

我的问题不是它不呈现,而是当我尝试调用'DequeueReusableHeaderFooterView'时,应用程序崩溃。 – fonix232

回答

0

这是因为如果没有HeaderFooterViews重用,return tableView.DequeueReusableHeaderFooterView(HeaderFooterView.Key);可以返回null。在这种情况下,你必须创建自己:

var view = tableView.DequeueReusableHeaderFooterView(HeaderFooterView.Key); 
if (view == null){ 
    //instantiate the nib here and set view 
} 

return view; 
+0

除了上面看到的错误('未捕获的异常:为标识符(HeaderFooterView)注册的无效nib - nib必须包含恰好一个顶级对象,它必须是UITableViewHeaderFooterView实例')会在'DequeueReusableHeaderFooterView'调用期间发生。我甚至不会检查视图是否为空,因为应用程序在该行上崩溃。 – fonix232

0

我建议构建的支持类,如下所示:

public partial class HeaderFooterView : MvxTableViewHeaderFooterView 
{ 
    public static readonly NSString Key = new NSString("HeaderFooterView"); 
    public static readonly UINib Nib = UINib.FromName("HeaderFooterView", NSBundle.MainBundle); 

    static HeaderFooterView() 
    { 
     //Adding this alone should allow your tableview to properly instantiate the view. 
     Nib = UINib.FromName("HeaderFooterView", NSBundle.MainBundle); 
    } 

    public static HeaderFooterView Create() 
    { 
     // However you can add this static method and create and return the view yourself. 
     var arr = NSBundle.MainBundle.LoadNib(nameof(HeaderFooterView), null, null); 
     var v = Runtime.GetNSObject<HeaderFooterView >(arr.ValueAt(0)); 
     return v; 
    } 

    public HeaderFooterView(IntPtr handle) : base(handle) 
    { 
     // Note: this .ctor should not contain any initialization logic. 
    } 

    public override void AwakeFromNib() 
    { 
     base.AwakeFromNib(); 
    } 
} 

添加本身的静态构造函数应该足以让你的表视图正确实例化Nib。不过,如果你还是最终不得不喜欢,你可以使用静态方法的问题“创建”实例笔尖自己是这样:

public override UIView GetViewForHeader(UITableView tableView, nint section) 
{ 
    HeaderFooterView theView = HeaderFooterView.Create() 
    return theView; 
} 

尝试这些建议,一方或双方应该为你工作。

+0

由于Nib字段已被静态初始化,因此不需要静态构造函数。另外我相信你的Create()方法将不起作用,因为它返回一个不同的类型。但我会尝试这种方法。 – fonix232

+0

@ fonix232对不起,这是一个复制和粘贴错误。我在回答中改变了返回类型。 – Digitalsa1nt

0

好的,找到了问题。

虽然我的初始XIB是正确的,出于某种原因,根对象的类型已被删除,并且Interface Builder拒绝接受我的。

但是,使用VS2017的Mac,我能够设置适当的根视图类,现在一切工作正常。

相关问题