Understanding Creating a Custom UITableCellView - Loading from Nibs to MonoTouch

I used this tutorial several times: http://www.alexyork.net/blog/2011/07/18/creating-custom-uitableviewcells-with-monotouch-the-correct-way/

But it has a section of code that I don't understand well:

cell = new MyCustomCell(); var views = NSBundle.MainBundle.LoadNib("MyCustomCell", cell, null); cell = Runtime.GetNSObject( views.ValueAt(0) ) as MyCustomCell; 

I tried to remove this - put LoadNib inside the constructors, but it went wrong, because the outputs are just not connected correctly.

Can anyone shed light on what is happening here? Why can't I load this Nib file inside the constructors? Why is it necessary to create two cell instances? What is actually happening in the background? Is it possible to improve the code?

Interested in learning about this, as I do this quite often, and I would like to make the process cleaner.

Stewart

If this helps, sample cell: https://github.com/slodge/MvvmCrossConference/blob/master/Cirrious.Conference.UI.Touch/Cells/SessionCell2.cs

+4
source share
1 answer

Look at things one at a time.

The LoadNib method unpacks (and instantiates) the contents of the NIB. The first parameter is the name of the NIB, and the second parameter is the owner of the loaded NIB. That is, the NIB "File Owner" guardian object, which in this case, I suppose, is just NSObject.

The LoadNib method also returns NSArray objects. These objects are top-level NIB objects, which in this case are a user cell created in the NIB.

I assume that when moving the above code in the constructor, you implement something like this:

 public MyCustomCell() : base() { NSBundle.MainBundle.LoadNib("MyCustomCell", this, null); } 

If you do not, and your implementation is different, but you still use LoadNib in the constructor, the outputs will not be saved anyway. They are created correctly, but they are not saved. This is not a MonoTouch GC that kicks or something else, this is a native output that is auto-implemented. You may be wondering: "But why can I use LoadNib in the UIViewController constructor and still get my weekend?". That's right, you can use LoadNib in the UIViewController constructor, but there is one important difference: UIViewController is the object of your file owner. If you try to do the same with a controller that is not a file owner, you will receive the same failure when saving outlets.

Basically you need the LoadNib method, which is a return array of top-level objects. Therefore, to make it work in the constructor, the โ€œcorrectโ€ way would be as follows:

  public MyCustomCell() : base() { NSArray arr = NSBundle.LoadNib("MyCustomCell", this, null); this = Runtime.GetNSObject(arr.ValueAt(0)); // should retain everything, //BUT: Compile error! } 

basically this is the same thing you do to load the NIB outside the constructor. But, of course, we cannot "this = something." So, let's summarize with the creation of LoadNib: your "MyCustomCell" is a top-level object, and it is provided to us through the return value of LoadNib, rather than passing it as an owner.

The next thing you noticed correctly is two examples: I believe that this is also wrong. Take a look at your code above, with some comments:

  cell = new MyCustomCell(); // Created a new instance of MyCustomCell var views = NSBundle.MainBundle.LoadNib("MyCustomCell", cell, null); // Assigned it as an owner cell = Runtime.GetNSObject( views.ValueAt(0) ) as MyCustomCell; // What happens to the owner? 

I think this is a memory leak. However, consider the following:

 // Not needed //cell = new MyCustomCell(); var views = NSBundle.MainBundle.LoadNib("MyCustomCell", tableView, null); // Owner is now the tableView cell = Runtime.GetNSObject( views.ValueAt(0) ) as MyCustomCell; views = null; // Don't need it anymore 

Now the owner of the NIB is a table view. The table view will be processed by the runtime (in most cases, at least).

If you still want to use LoadNib inside your MyCustomCell class to instantiate, just create a static method:

 // Inside MyCustomCell public static MyCustomCell CreateCell(NSObject owner) { NSArray topLevelObjects = NSBundle.MainBundle.LoadNib("MyCustomCell", owner, null); MyCustomCell customCell = Runtime.GetNSObject(topLevelObjects.ValueAt(0)) as MyCustomCell; topLevelObjects = null; return customCell; } 

More on downloading NIB:

Can you nib this?

Apple Resource Programming Guide for NIB Files

Hope this helps.

+5
source

Source: https://habr.com/ru/post/1403463/


All Articles