2017-07-12 60 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,我能夠設置適當的根視圖類,現在一切工作正常。

相關問題