3

In an app I am building I use the following pattern: If the user clicks on a hierarchical navigation element I open the next UIViewController immediately, and it takes care about loading its data itself and shows a loading spinner if it is going over the network.

Now most list views are created using MonoTouch. On one DialogViewController I have an issue with adding many element to the views RootElement after the screen has already been show.

At first the StringElements appear fine on screen, but if you scroll quickly up and down the text on each line becomes a block:

screenshot of the issue at hand

Code to reproduce the issue:

        var root = new RootElement("Root");
        var dvc = new DialogViewController(root) { AutoHideSearch = true, EnableSearch = true };

        nav.PushViewController(dvc, true);

        Task.Factory.StartNew(() => {
                Thread.Sleep(TimeSpan.FromSeconds(1));
            UIApplication.SharedApplication.InvokeOnMainThread(() => {
                var sec = new Section();

                for (int i = 0; i < 100; i++)
                {
                    var el = new StyledStringElement("Test", "Test", UITableViewCellStyle.Value1);
                    sec.Add(el);
                }

                root.Add(sec);
            });
        });

Interestingly only the string on the left looks like a block, while the one on the right is fine. On a side note, in their MWC (demo) app, Xamarin created a new RootElement to repopulate the twitter list as well.

Timm
  • 2,652
  • 2
  • 25
  • 34

2 Answers2

3

There does not seem to be a reload of the data source called on the main thread to correctly render the new values:

var dvc = new DialogViewController(new RootElement(""));
_root = new UINavigationController();
_root.PushViewController(dvc, true);
_window.RootViewController = _root;

Task.Factory.StartNew(() => {
    Thread.Sleep(TimeSpan.FromSeconds(1));
    var section = new Section("");
        foreach (var i in Enumerable.Range(1, 100)) {
            section.Add(new StyledStringElement(i.ToString(), "cell", UITableViewCellStyle.Value1));
        }

    dvc.Root.Add(section);
    BeginInvokeOnMainThread(() => {
        dvc.ReloadData();
    });
});
Anuj
  • 3,134
  • 13
  • 17
  • But how come it works at first, and breaks after scrolling down and up again? – Timm Feb 26 '12 at 21:20
  • Sorry it seems my initial hypothesis was wrong. I'm adjusting the answer. – Anuj Feb 26 '12 at 21:42
  • Adding `dvc.ReloadData();` indeed fixes the behavior. But from my limited understanding this is a bug I should file. Please vote on the question since you found it worthwhile to answer ;-) I will wait with the "accept" until I hear back from the bug report. – Timm Feb 27 '12 at 13:30
  • had the problem .. i decided to create an element by my self to fix the issue. – Janub Feb 28 '12 at 07:40
0

I exactly have the same issue when I'm rendering dynamically the element in an BeginInvokeOnMainThread statement If I do load my elements in the constructor, the UI is blocked but the elements will render well.

and thanks for the tip dvc.ReloadData will work as well for me

Ronny
  • 105
  • 7