Archive for December, 2014

UITableView not showing data / refreshing while data is there

Was in Xamarin, but the same issue applies to ObjC/XCode. 

It was a late night on the 25th and when I got up quite early the 26th to some inspiration for coding I added a UITableView like I did so many times before. I added the source and thought all was fine. But it didn’t work. It didn’t show anything.

First I decided to view.SetNeedsDisplay() and that actually then did show the table, but without any data. Just a BackgroundColor rectangle. At least now it had BackgroundColor and not white (the color of Superview.BackgroundColor).

After a lot of swearing I found that;

  1. this.ReloadRows (new NSIndexPath[]{ NSIndexPath.FromItemSection (0, 0) }, UITableViewRowAnimation.None);

would actually load and show all data.

But the table wouldn’t scroll and you could not select any rows; this, in my tired mind, made an alarm go off. I did this so many times before and it always worked, this time it didn’t and all stackoverflow answers where based on mistakes I had not made for a long time, so it must be another mistake.

It took me 1 hour to figure out what was going on as I did not know that tableviews who do not receive inputs do not get refreshed which is related to the UIViews which receive no inputs not getting they LayoutSubviews() called.

Long story short; the UITableView was in a UIView which was not big enough and ClipToBounds was false, so it did show up but nothing else. My overlapping tools and debugging tools did not detect this, so I lost any hour.

In my library I have all Apple view classes inherited by my own for tooling, debugging and convenience methods, so it was not hard to fix this once and for all by overriding Frame{get;set;} and, for DEBUG add the following which warns me and makes sure I actually checked everything (ShowStack is an Extension which allows me to see the linenumber + file name the issue happens to be appear in);

  1. public override System.Drawing.RectangleF Frame {
  2.             get {
  3.                 return base.Frame;
  4.             }
  5.             set {
  6.                 base.Frame = value;
  8.                 if (Superview == null)
  9.                     return;
  11.                 if (value.X < 0
  12.                     ||
  13.                     value.X > Superview.Frame.Width
  14.                     ||
  15.                     value.X + value.Width > Superview.Frame.Width
  16.                     ||
  17.                     value.Y < 0
  18.                     ||
  19.                     value.Y > Superview.Frame.Height
  20.                     ||
  21.                     value.Y + value.Height > Superview.Frame.Height) {
  23.                      this.ShowStack   (“Warning: Frame is out of bounds of the superview frame:+ this.ToString() + “ trying to fit in+ Superview.ToString(),1);
  24.                 }
  25.             }        
  26.   }

Edit: The data loading issue is not related to this, but I don’t know yet what it is related to. I just call ReloadRows for now as I have no time to debug it.